
我正在創建一個 sh 文件以在後台運行多個命令。
在該檔案的某行,有一個用於更新 zip 檔案的命令,例如:
zip -d archive.zip file.txt
此 file.txt 可能並不總是 archive.zip 的一部分。如果不是,shell 腳本會在該行中中斷:
zip warning: name not matched
我希望它繼續到以下幾行,忽略該文件的不存在。我怎樣才能做到這一點?
答案1
通常在 shell 腳本中,即使是產生錯誤的行也不會阻止 shell 腳本的執行。它只會繼續到下一行。
值得注意的例外是,如果您設定了標誌,以便在任何子命令失敗時退出 shell。有時可以透過在腳本頂部附近添加“set -e”來完成。如果您的腳本中有類似的內容,它將在腳本中的任何命令返回錯誤時中止。在這種情況下,您的選擇是:
刪除該選項。這可能會對腳本的其餘部分產生影響,因此不要一時興起這樣做。
關閉您所在腳本部分的選項,然後重新開啟以繼續:
set +e zip -d archive.zip file.txt set -e
為失敗的行提供一條出路,以便 shell 即使故障也將命令視為成功。可以透過多種方式完成此操作,但一種簡單的方法是使用 OR 運算子:
zip -d archive.zip file.txt || true
這將運行 zip 命令,但如果失敗,它將運行 true 命令,父 shell 將從中獲取返回程式碼(當然,這是成功的)。你可能會看到有時這樣寫,
||:
它稍微快一些,更棘手,但並不神奇;:
只是碰巧是一個 shell 內建無操作命令,即使它什麼都不做,也會回傳成功錯誤代碼。另一種方法是在子 shell 中執行該命令,將其包圍起來,
()
因此雖然其中的命令可能會失敗,但子 shell 會完成其工作,因此帶有set -e
set 的父腳本不會終止。對於單一命令來說,這不是最佳選擇,但如果您想執行一整套命令,這可能會很有用。
另一方面,如果您只想抑制 zip 產生的錯誤訊息,則可以使用 ( 2> /dev/null
) 將標準錯誤流重定向到 /dev/null 以抑制產生的訊息(或使用 關閉它2>&-
)。