如何查看"bash -c ''"执行的命令的错误码?

How to check the error code of a command executed by "bash -c ''"?

我在以下示例中调用了 RSYNC。由于各种原因,还需要 RSYNC 的错误代码,并在语句后使用 $? 检索。 AFAIK 即使在此示例中执行了两个命令,错误代码实际上应该是 RSYNC 而不是 NICE。不过,我不知道 NICE 是故意转发该 RSYNC 代码还是用 RSYNC 替换自身,以便仅生成该代码。反正没关系,接收到的代码正确映射到 RSYNC 的行为方式。

/[...]/nice [...] /[...]/rsync [...]

上面的语句也需要更改为记录 RSYNC 的输出。据我了解,这与 SUDO 等其他情况非常相似,其中在同一级别添加 shell 重定向不起作用。 shell 重定向将覆盖 NICE 的输出而不是 RSYNC,这可能取决于 NICE 在内部的实际工作方式。无论如何,开始一个新的 shall 和它自己的特定重定向应该总是安全的,就像下面的例子:

/[...]/nice [...] bash -c "/[...]/rsync [...] > [...] 2>&1"

重点是:$? 在该语句之后立即检索哪个错误代码?

是BASH return最后执行命令的错误代码还是总是return 0,因为它自己执行成功了?如果它转发 RSYNC 的错误代码,一切都会很好,就像过去不使用中间 BASH 一样。 OTOH,如果出现错误,可能需要额外触发 BASH 退出,可能会以这种方式转发最后一个错误代码:

/[...]/nice [...] bash -c "set -o errexit ; /[...]/rsync [...] > [...] 2>&1"

我已经在 shell 上用 rsync --versionrsync --version_ 测试了第二个和第三个例子,后者导致了预期的 RSYNC 错误消息。在这两种情况下,似乎 BASH 正确地 returns 是 RSYNC 本身的错误代码。虽然,我找不到太多关于该行为的文档,例如使用 -c 等执行多个命令时会发生什么

那么,如何正确检查使用bash -c '[...]'执行的命令的错误代码呢?是例如set -o errexit 完全必要,它甚至会有害吗?

谢谢!

Bash的退出代码是它执行的最后一个命令的退出代码。

set -e / set -o errexit 不会改变这一点。通过实验很容易建立:

bash$ bash -c 'exit 17'; echo $?
17
bash$ bash -c 'set -e; bash -c "exit 17"; echo still here'; echo $?
17
bash$ bash -c 'set -e; nice -1 bash -c "exit 17"; echo still here'; echo $?
17