使用while循环时的Bash退出状态

5
我有一个Bash脚本,可以逐个ping一系列IP地址。如果每次ping的退出状态为0,则会输出节点已上线,否则该节点已下线。我能够完美地运行这个脚本,但是当Bash脚本结束时,退出状态总是为0。
我的目标是,例如在5个IP地址中,如果第3个失败了,则继续检查列表中的其余IP地址,但一旦脚本结束,抛出非0的退出状态并输出哪个IP地址失败了。
cat list.txt |  while read -r output
do
    ping -o -c 3 -t 3000 "$output" > /dev/null
    if [ $? -eq 0 ]; then
    echo "node $output is up"
    else
    echo "node $output is down"
    fi
done

感谢您的提前帮助!
1个回答

8
你的第一个问题是,通过执行cat file | while read,你已经在其自己的子shell中生成了while。它设置的任何变量仅存在于该循环期间,因此持久化值将会很困难。有关该问题的更多信息,请单击此处。 如果使用while read ... done < file,它将正常工作。创建一个退出状态标志,默认值为零,但如果出现任何错误,则将其设置为一。将其用作脚本的退出值。
had_errors=0

while read -r output
do
    ping -o -c 3 -t 3000 "$output" > /dev/null
    if [ $? -eq 0 ]; then
        echo "node $output is up"
    else
        echo "node $output is down"
        had_errors=1
    fi
done < list.txt

exit $had_errors

这看起来正在做我想要的事情。我不知道第一个问题,现在我明白了。谢谢! - user2683183
1
cmd; if [ $? -eq 0 ]; then 几乎总是最好替换为 if cmd; then - Etan Reisner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接