重定向 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其他可行的解决方案
- Write black output into a variable:这似乎可行,目前是我的首选解决方案。
- 将黑色输出写入文件,然后将文件输入输入错误解析器:对于我想要实现的目标,此解决方案似乎有点矫枉过正。
系统信息
- 黑色: 19.10b0
- bash: GNU bash, 版本 5.0.17(1)-release (x86_64-pc-linux-gnu)
- os: Ubuntu 20.04
- 内核: 5.4.0-58-generic
与
相关
- Redirect stdout and stderr to different program without changing exit code
解决方案总结
正如 @charles-duffy 所指出的,退出代码的问题是由接收命令无法处理 stderr
引起的。在我的例子中,这是因为我允许操作用户向错误解析器提供不受支持的标志,这导致错误解析器 return 帮助对话框。因此,发送命令的退出代码更改为 1
.
这一点也不奇怪。
请记住,管道将左侧内容的标准输出(以及您的重定向,stderr)连接到右侧内容的标准输入。
如果右边的东西不读取它的标准输入,这意味着左边的东西不能写入标准输出或标准错误。因此,如果它尝试执行这样的写入,预计会出现错误。因此,它应该有一个反映该错误的退出状态。
echo
根本不从标准输入读取;它只是写入标准输出,然后退出。因此,输入 echo
的管道左侧的任何内容都无法成功写入内容。
我目前正在创建一个 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其他可行的解决方案
- Write black output into a variable:这似乎可行,目前是我的首选解决方案。
- 将黑色输出写入文件,然后将文件输入输入错误解析器:对于我想要实现的目标,此解决方案似乎有点矫枉过正。
系统信息
- 黑色: 19.10b0
- bash: GNU bash, 版本 5.0.17(1)-release (x86_64-pc-linux-gnu)
- os: Ubuntu 20.04
- 内核: 5.4.0-58-generic
与
相关- Redirect stdout and stderr to different program without changing exit code
解决方案总结
正如 @charles-duffy 所指出的,退出代码的问题是由接收命令无法处理 stderr
引起的。在我的例子中,这是因为我允许操作用户向错误解析器提供不受支持的标志,这导致错误解析器 return 帮助对话框。因此,发送命令的退出代码更改为 1
.
这一点也不奇怪。
请记住,管道将左侧内容的标准输出(以及您的重定向,stderr)连接到右侧内容的标准输入。
如果右边的东西不读取它的标准输入,这意味着左边的东西不能写入标准输出或标准错误。因此,如果它尝试执行这样的写入,预计会出现错误。因此,它应该有一个反映该错误的退出状态。
echo
根本不从标准输入读取;它只是写入标准输出,然后退出。因此,输入 echo
的管道左侧的任何内容都无法成功写入内容。