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:
- Is the yes piping still functional, even though yes reports error?
- How can I fix it?
Saying:
causes
head
to send aSIGPIPE
toyes
once it's done reading 3 lines of input, i.e. it'd send a signal to terminateyes
.The solution would be to avoid a
SIGPIPE
!the other question answers the why ... I'll try and give you a work around
could you not do something like
see below (I didnt bother with the delay since head isnt really doing much)
The issue is that
subprocess
module before Python 3.2+ doesn't restoreSIGPIPE
signal handler to default action. That is why you getEPIPE
write error instead.In Python 3.2+
yes
is killed bySIGPIPE
whenhead
exits.In Python 2:
yes
gotEPIPE
write error. It is safe to ignore the error. It communicates the same information asSIGPIPE
.To workaround the problem, you could emulate
restore_signals
in Python 2 usingpreexec_fn
parameter :