如果 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 -e
非source
d 脚本的工作方式?
答案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
。