unix - piping with error checking using subprocess in python -
i have piping scheme using subprocess
1 process p2
takes output of process p1
input:
p1 = subprocess.popen("ls -al", shell=true, stdout=subprocess.pipe, stderr=subprocess.pipe) p2 = subprocess.popen("grep mytext - ", shell=true, stdin=p1.stdout, stdout=subprocess.pipe) result = p2.communicate()
p1
or p2
fail various reasons, wrong inputs or malformed commands.
this code works fine when p1
not fail. how can check whether p1
or p2
failed? example:
# p1 fail since notafile not exist p1 = subprocess.popen("ls notafile", shell=true, stdout=subprocess.pipe, stderr=subprocess.pipe) p2 = subprocess.popen("grep mytext - ", shell=true, stdin=p1.stdout, stdout=subprocess.pipe) result = p2.communicate()
i can check p2.returncode
, see it's not 0
, mean p2
failed or p1 failed. how can check whether p1
failed or p2
failed in cases pipe goes wrong?
i don't see how can use p1.returncode
ideal , obvious solution. ex:
p1 = subprocess.popen("ls foo", shell=true, stdout=subprocess.pipe, stderr=subprocess.pipe) p2 = subprocess.popen("grep mytext - ", shell=true, stdin=p1.stdout, stdout=subprocess.pipe) # here, p2.returncode not defined yet since didn't communicate() assert(p2 none) r = p2.communicate() # p2 has returncode assert(p2.returncode not none) # ... p1 not! assert(p1.returncode none)
so don't see how returncode helps here?
the full solution @abarnert this:
p1 = subprocess.popen("ls -al", shell=true, stdout=subprocess.pipe, stderr=subprocess.pipe) p2 = subprocess.popen("grep mytext - ", shell=true, stdin=p1.stdout, stdout=subprocess.pipe) result = p2.communicate() if p2.returncode != 0: # failed if p1.wait() != 0: # p1 failed... else: # p2 failed...
p.s. know caveats of shell=true
security.
i can check result.returncode , see it's not 0, mean p2 fail.
no, can't; result
tuple (stdoutdata, stderrdata)
.
it's popen
objects have returncode
values.
and that's answer here:
how can check whether p1 failed or p2 failed in cases pipe goes wrong?
just check p1.returncode
.
however, aware while p2.communicate
does guarantee p2
has been wait
ed on, not guarantee same p1
. fortunately, should guarantee p1
@ least wait
able, not wait
ed, so:
if p2.returncode: if p1.wait(): # p2 failed, because p1 failed else: # p2 failed other reason
except want p1.stdout.close()
right before communicate
. otherwise, it's possible error in process 2 leave process 1 blocked, , therefore p1.wait()
block forever. (you work around using p1.poll()
here , killing if it's not finished, really, it's better not create problem work round it.)
one last thing: you've set p1.stderr
subprocess.pipe
, never gets attached anything, it's possible process 1 block trying write overflowing stderr pipe. may want fix well.
Comments
Post a Comment