python - 管道连接导致从 python 调用的 shell 脚本中的管道损坏

标签 python bash shell pipe head

我有一个生成随机字符串的命令:

var=`< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c8`

当我在交互式 bash session 中运行此命令时,我完全没有收到任何错误。但是当我将此命令放入脚本并将其作为脚本运行时,我得到了 tr 指示的 Broken pipe 错误。我已经阅读了几个相关主题,但仍然没有答案为什么脚本和交互行为不同,有没有办法用 shell 选项或其他东西来控制它?

编辑一:

关于给出的评论,我发现指示损坏的管道错误可以通过以下方式控制:

 trap - SIGPIPE # to ignore errors

 trap "" SIGPIPE # to display errors

编辑二:

好吧,我提供了有关复制条件的错误信息。最后,问题似乎是由使用 os.system() 调用脚本的 python 包装器引起的:

 python -c "import os; os.system('sh -c \"< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c8\"')"

给定的行会独立于所使用的操作系统产生损坏的管道错误。

编辑三:

此主题已在此处讨论: https://mail.python.org/pipermail/python-dev/2005-September/056341.html

最佳答案

如果其中一个父进程捕获 sigpipe,则管道将继承 ignore 信号配置,这将导致您遇到这个问题。

这可以(安全地)复制:

( trap '' pipe; var=`< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c8` )

通常,head -c8 命令会很快完成,此时它的 stdin 会关闭。因为它的 stdin 是连接到 trstdout 的管道,所以现在 tr 不再有意义写入其 stdout。一旦尝试,系统将使用 SIGPIPE 杀死它。 除非 tr 忽略此信号或已从其父级继承此信号的 ignore (SIG_IGN) 处置。然后 writetr 损坏的 stdout 只会导致常规错误并将 errno 设置为 EPIPE 此时 tr 最有可能将此错误字符串化并将此错误输出到其 stderr 并退出。

关于python - 管道连接导致从 python 调用的 shell 脚本中的管道损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33020759/

相关文章:

python - 为什么Python会选择这个意想不到的模块来导入

c - 是否可以像 C 一样在 shell bash 函数中将变量定义为静态变量?

html - HTML 中 URL 的正则表达式匹配

php ffmpeg 获取视频时长

python,在特定范围内随机排列列表数组?

python - 用 importlib 替换 imp 以保持旧行为?

python - 这个 Bokeh 列数据源是如何工作的?

bash - 在 Ubuntu 上,bash 脚本总是返回 0,即使设置了 set -o errexit

bash - 如何将文本粘贴到像 awk 这样的逐行文本过滤器,而不让标准输入回显到屏幕?

Python 3.1 : Syntax Error for Everything! (Mac OS X)