条件满足时Bash脚本不会继续

时间:2019-09-07 12:24:35

标签: bash

要检查文件中各行的有效性,我使用了egrep -v不返回空结果时要满足的条件。如果有无效行,则可以正常工作(即执行条件块),但是当每一行都有效时,脚本将结束而无需进一步处理。

脚本:

INVALID_HOSTS=$(egrep -v ${IP_REGEX} hosts)
if [[ ! -z "${INVALID_HOSTS}" ]]; then
    echo "Invalid hosts:"
    for entry in ${INVALID_HOSTS}
        do echo ${entry}
    done
    exit_with_error_msg "hosts file contains invalid hosts (Pattern must be: \"\d+.\d+.\d+.\d+:\d+\"), exiting"
else
    echo "all cool"
fi
echo "after if-else"

因此,当没有无效行时,echo "all cool"echo "after if-else"都不会执行。该脚本只是停止并返回到外壳。

启用set -x后,它会打印:

++ egrep -v '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?):([1-9]|[1-5]?[0-9]{2,4}|6[1-4][0-9]{3}|65[1-4][0-9]{2}|655[1-2][0-9]|6553[1-5])$' hosts
+ INVALID_HOSTS=

尝试使用它,我确信它与if [[ ! -z "${INVALID_HOSTS}" ]]; then有关,但是我的bash向导能力不足以克服这个魔术障碍。

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

这有点长,可以发表评论。我将以它作为答案开始,我们可以逐步解决更多细节,或者如果没有帮助,也可以将其完全废弃。我会做一些假设,然后让我们看看它是否达到目标。

对于初学者来说,确实确实会进一步使用该值,因此将命令扩展为变量并非完全没有用,但是通过它的返回值来确定grep的匹配(或缺少匹配)要容易得多。如果有任何匹配的内容(输出为非空),它将返回true的(shell 0)值,否则返回false(在这种情况下为1)。更不用说! -z测试符号了,如果真的使用的话,应该真的是-n

这就是我开始假设的地方。我怀疑这不是您的整个脚本,并且您在该Shell会话中打开了errexit选项(或通常通过rc文件)。通过set -o errexitset -e或通过-e选项运行bash。由于grep不匹配任何内容,将返回失败,因此您的shell(脚本执行)将在遇到失败的命令后终止。

观察两者之间的区别:

$ bash -ec 'grep "BOGUS" /etc/fstab  ; echo "$?"'
$ bash -c 'grep "BOGUS" /etc/fstab  ; echo "$?"'
1

对于errexit,bash在grep“失败”之后终止,我们甚至从未到达echo


由于该假设已被证明是正确的,因此请稍作扩展。如果您要使用errexit,则需要在不影响脚本的情况下在希望失败的命令之前或之后更改选项值(返回非零值):

set +o errexit
grep THIS_COULD_NOT_MATCH...
set -o errexit

或者您可以通过确保单个命令的成功来忽略它们的返回值:

grep THIS_COULD_NOT_MATCH... || true

您还可以在条件(例如if)中安全使用潜在的“失败”命令,而无需终止外壳程序。