Bash return 使用 heredoc 输入时的代码错误处理

Bash return code error handling when using heredoc input

动机

我处于这样一种情况,我必须通过单个 bash 调用 运行 多个 bash 命令,而无法编写完整的脚本文件(用例:). A 是将命令与;&&组合起来,例如:

bash -c " \
echo \"Hello World\" ; \
ls -la ; \
run_some_command "

在实践中编写 bash 这样的脚本很容易出错,因为我经常忘记分号导致细微的错误。

受到 this question 的启发,我尝试使用 heredoc 以更标准的样式编写脚本:

bash <<EOF
echo "Hello World"
ls -la
run_some_command
EOF

不幸的是,我注意到使用 heredoc 时退出代码错误处理有所不同。例如:

bash -c " \
run_non_existing_command ; \
echo $? "

输出(注意 $? 正确捕获退出代码):

bash: run_non_existing_command: command not found
127

bash <<EOF
run_non_existing_command
echo $?
EOF

输出(请注意,与标准脚本执行相比,$? 无法捕获退出代码):

bash: line 1: run_non_existing_command: command not found
0

为什么 heredoc 版本的行为不同?是否可以用 heredoc 风格编写脚本并保持正常的退出代码处理?

Why is the heredoc version behaving differently?

因为 $? 在 运行 命令之前展开。

下面会输出1,即false命令的退出状态:

false
bash <<EOF
run_non_existing_command
echo $?
EOF

和下面的原理一样,都会打印5:

variable=5
bash <<EOF
variable="This is ignored"
echo $variable
EOF

Is it possible to write the script in the heredoc style and maintaining normal exit code handling?

如果你想让 $? 在 subshel​​l 中展开,那么:

bash <<EOF
run_non_existing_command
echo $?
EOF

bash <<'EOF'
run_non_existing_command
echo $?
EOF

另请注意:

bash -c \
run_non_existing_command ;
echo $? ;

正好等于:

bash -c run_non_existing_command
echo $?

echo $?bash -c内部没有执行。