命令失败时自动返回 `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

如果你的文件来源文件脚本只有一行命令就可以工作。
距离投入生产环境还有很长的路要走。
测试一下,最终需要您自担风险使用它

它会跳过以 开头的行,#因为它们会导致错误# command not found

相关内容