I am using the following function to run a command in Python:
def run_proc(cmd):
child = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = child.communicate()
returncode = child.returncode
return stdout, stderr, returncode
It has always been working fine, however now I'm trying to use the yes
program to pipe output to stdin. The command I'm trying to run is the following:
yes '' | apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade
but I believe it could be substituted with a general example, like:
yes | head -3 | cat
My problem is that if I try to run any command which has yes |
in it, the above subprocess.Popen will contain the error messages:
yes: standard output: Broken pipe
yes: write error
For me it seems that the piping still works, as can be seen from yes | head -3 | cat
's answer: y y y
.
I have the following questions:
The issue is that subprocess
module before Python 3.2+ doesn't restore SIGPIPE
signal handler to default action. That is why you get EPIPE
write error instead.
In Python 3.2+
>>> from subprocess import check_output
>>> check_output("yes | head -3", shell=True)
b'y\ny\ny\n'
yes
is killed by SIGPIPE
when head
exits.
In Python 2:
>>> from subprocess import check_output
>>> check_output("yes | head -3", shell=True)
yes: standard output: Broken pipe
yes: write error
'y\ny\ny\n'
yes
got EPIPE
write error. It is safe to ignore the error. It communicates the same information as SIGPIPE
.
To workaround the problem, you could emulate restore_signals
in Python 2 using preexec_fn
parameter :
>>> from subprocess import check_output
>>> import signal
>>> def restore_signals(): # from http://hg.python.org/cpython/rev/768722b2ae0a/
... signals = ('SIGPIPE', 'SIGXFZ', 'SIGXFSZ')
... for sig in signals:
... if hasattr(signal, sig):
... signal.signal(getattr(signal, sig), signal.SIG_DFL)
...
>>> check_output("yes | head -3", shell=True, preexec_fn=restore_signals)
'y\ny\ny\n'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With