python - 从终端运行和从 Python 运行时脚本的工作方式不同

标签 python bash subprocess pipeline

我有一个简短的 bash 脚本 foo.sh

#!/bin/bash

cat /dev/urandom | tr -dc 'a-z1-9' | fold -w 4 | head -n 1

当我直接从 shell 运行它时,它运行良好,完成后退出

$ ./foo.sh 
m1un
$

但是当我从 Python 运行它时

$ python -c "import subprocess; subprocess.call(['./foo.sh'])"
ygs9

它输出该行,但随后就永远挂起。是什么导致了这种差异?

最佳答案

trap -p 命令添加到 bash 脚本,停止挂起的 python 进程并运行 ps 显示发生了什么:

$ cat foo.sh
#!/bin/bash

trap -p
cat /dev/urandom | tr -dc 'a-z1-9' | fold -w 4 | head -n 1

$ python -c "import subprocess; subprocess.call(['./foo.sh'])"
trap -- '' SIGPIPE
trap -- '' SIGXFSZ
ko5o

^Z
[1]+  Stopped     python -c "import subprocess; subprocess.call(['./foo.sh'])"
$ ps -H -o comm
COMMAND
bash
  python
    foo.sh
      cat
      tr
      fold
  ps

因此,subprocess.call() 执行命令并屏蔽了 SIGPIPE 信号。当 head 完成其工作并退出时,其余进程不会收到 broken pipe 信号并且不会终止。

有了手头问题的解释,很容易找到python bugtracker中的bug,原来是issue#1652 .

关于python - 从终端运行和从 Python 运行时脚本的工作方式不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39397034/

相关文章:

swift - 在终端中执行 Swift 脚本

python - 将 mmap 与 popen 一起使用

python - 将函数列表应用于 python 中的参数列表

python - 当我尝试将 excel 文件转换为列表时,“DataFrame”对象没有属性 'tolist'

linux - bash 脚本和 awk 对文件进行排序

mysql 将多行导入为一条记录

Python:从脚本中打开一个名为 xls 的 unicode 文件

python - 使用自定义采样率将 Mp3 转换为 Wav

python - 与列表和长度一起使用的 while 语句

python - 我可以按列分组并重新采样日期吗?