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 waited on, not guarantee same p1. fortunately, should guarantee p1 @ least waitable, not waited, 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

Popular posts from this blog

c++ - Creating new partition disk winapi -

Android Prevent Bluetooth Pairing Dialog -

VBA function to include CDATA -