重定向 stderr 更改管道命令的退出代码

Redirecting stderr changes exit codes of piped command

我目前正在创建一个 GitHub-action 来格式化 python 代码,同时还创建注释。为了实现这一点,我管道 black python formatter into the std_in of the reviewdog error parser. While doing so, I, however, want to access the exit code of the black formatter. After researching, I found out that the PIPESTATUS 的 stderr 正是为这个 purpose 创建的。因此,我目前使用以下代码尝试检索管道黑色命令的退出代码:

black --check .
echo "Black non-piped exit code: $?"
black --check . 2>&1 | echo "jan"
PC=(${PIPESTATUS[@]})
echo "Black piped exit code: ${PC[0]}"

>
Black non-piped exit code: 0
Black piped exit code: 1

令人惊讶的是,管道访问代码始终是 1,即使黑色 return 是 0 退出代码也是如此。当我删除 2>&1 重定向时,这种行为消失了:

black --check .
echo "Black non-piped exit code: $?"
black --check . | echo "jan"
PC=(${PIPESTATUS[@]})
echo "Black piped exit code: ${PC[0]}"

>
Black non-piped exit code: 0
Black piped exit code: 0

因此,它会查看 std_err 重定向是否更改了 PIPESTATUS 变量中的退出代码。不幸的是,我还不知道为什么会发生这种情况以及如何防止这种情况发生。我有另外两个解决方案可以让我实现所需的行为,但我很好奇发生了什么。因此,如果有人能向我解释发生了什么,我将不胜感激。非常感谢!

Pos其他可行的解决方案

系统信息

相关

解决方案总结

正如 @charles-duffy 所指出的,退出代码的问题是由接收命令无法处理 stderr 引起的。在我的例子中,这是因为我允许操作用户向错误解析器提供不受支持的标志,这导致错误解析器 return 帮助对话框。因此,发送命令的退出代码更改为 1.

这一点也不奇怪。

请记住,管道将左侧内容的标准输出(以及您的重定向,stderr)连接到右侧内容的标准输入。

如果右边的东西不读取它的标准输入,这意味着左边的东西不能写入标准输出或标准错误。因此,如果它尝试执行这样的写入,预计会出现错误。因此,它应该有一个反映该错误的退出状态。

echo 根本不从标准输入读取;它只是写入标准输出,然后退出。因此,输入 echo 的管道左侧的任何内容都无法成功写入内容。