我想在一个循环的代码块中中断和错误,当循环中的任何命令返回1.我想在没有子shell的情况下执行此操作。
while read file; do
command_one_that_might_error_out;
command_two_that_might_error_out;
command_three_that_might_error_out;
done < <(ls -1 .) || echo "something bad when of the commands ran happened";
任何人都可以提供见解吗?
答案 0 :(得分:1)
在脚本顶部试试set -e
。当你处于set -u
时,一般都是良好的bash卫生。
答案 1 :(得分:1)
您可以将|| break
放在每个命令的末尾,但是break
会返回0,因此您的最终|| echo "something bad happened"
将无法执行。
您可以使用break 0
,break
将以非零代码退出,但它也会写入错误(可能会重定向)。您可以通过全局变量传播错误代码,如Gordon Davisson的回答所示。
您可以将break
命令放在一个函数中,以使其更清晰并捕获error_code:
break_fail() { break 0 2>/dev/null ; }
break_error() { error_code=$? ; break 0 2>/dev/null ; }
error_code=0
while read file; do
command_one_that_might_error_out || break_error
command_two_that_might_error_out || break_error
command_three_that_might_error_out || break_error
done < <(ls -1 .) || echo "something bad happened: Error $error_code"
但这并没有告诉你哪个命令返回了错误。
如果你需要处理特定的错误代码,我建议在循环中内联处理它们并使用break_fail进行分解。
答案 2 :(得分:1)
我还没有测试过,但这应该可行:
err_val=0
while read file; do
command_one_that_might_error_out || { err_val=$?; break; }
command_two_that_might_error_out || { err_val=$?; break; }
command_three_that_might_error_out || { err_val=$?; break; }
done < <(ls -1 .)
if [ $err_val -ne 0 ]; then
echo "something bad happened"
fi
答案 3 :(得分:0)
最简单的方法可能是使用$?
,这是最后一个命令的返回值。所以你要添加
if [[ "$?" = "1" ]]; then
break
fi
在每个命令之后。