Mike Graham Mike Graham - 2 months ago 12
Python Question

Script works differently when ran from the terminal and ran from Python

I have a short bash script

foo.sh


#!/bin/bash

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


When I run it directly from the shell, it runs fine, exiting when it is done

$ ./foo.sh
m1un
$


but when I run it from Python

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


it outputs the line but then just hangs forever. What is causing this discrepancy?

Answer

Adding the trap -p command to the bash script, stopping the hung python process and running ps shows what's going on:

$ 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

Thus, subprocess.call() executes the command with the SIGPIPE signal masked. When head does its job and exits, the remaining processes do not receive the broken pipe signal and do not terminate.

Having the explanation of the problem at hand, it was easy to find the bug in the python bugtracker, which turned out to be issue#1652.

Comments