命令失敗時自動返回“source”腳本

命令失敗時自動返回“source”腳本

如果 d腳本中的任何命令失敗,如何使其source自動返回?

假設我有一個在失敗時自動退出的腳本set -e,例如

#!/bin/bash
# foo.env
set -e        # auto-exit on any command failure
echo "hi"
grep 123 456  # this command will fail (I don't have a file named "456")
echo "should not reach here"

如果我正常運行該命令,它將在命令失敗時自動退出grep

box1% ./foo.env
hi
grep: 456: No such file or directory

但是,如果我source執行腳本,它會退出我目前的 shell,而不僅僅是所取得的腳本:

box1% ssh box2
box2% source ./foo.env
hi
grep: 456: No such file or directory
Connection to box2 closed.
box1%

如果我刪除set -e

#!/bin/bash
# foo2.env
echo "hi"
grep 123 456  # this command will fail (I don't have a file named "456")
echo "should not reach here"

source那麼它根本不會自動退出或自動返回d 腳本:

box1% ssh box2
box2% source ./foo2.env
hi
grep: 456: No such file or directory
should not reach here
box2%

到目前為止我發現的唯一解決方法是return為腳本中的每一行程式碼添加一個表達式,例如

box1% cat foo3.env
#!/bin/bash
# foo3.env - works, but is cumbersome
echo "hi" || return
grep 123 456 || return
echo "should not reach here" || return

box1% source foo3.env
hi
grep: 456: No such file or directory
box1%

d 腳本是否有另一種方法source,類似於set -esourced 腳本的工作方式?

答案1

當您source編寫腳本時,就像您從鍵盤逐行編寫該檔案一樣。這意味著set -e將考慮當前 shell,並且在出錯時將從目前 shell 退出。

這是一個解決方法。今天我覺得我很懶,所以我認為計算機可以||return為我編寫,或者更好地逐行讀取文件並執行:

#!/bin/bash
# this is the file MySource.sh
while IFS='' read -r line
do
   [[ $line == \#* ]] || $line || return
done < "$1"

執行它. MySource.sh FileToBeSourced.sh

如果你的FileToBeSourced.sh腳本包含一行命令,它應該可以工作。
離準備在生產環境中使用還很遠。
測試一下,最終需要您自擔風險使用它

它會跳過以 開頭的行,#因為它們會導致錯誤# command not found

相關內容