Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine subprocess.Popen() failed when shell=True

Windows version of Python 2.6.4: Is there any way to determine if subprocess.Popen() fails when using shell=True?

Popen() successfully fails when shell=False

>>> import subprocess
>>> p = subprocess.Popen( 'Nonsense.application', shell=False )
Traceback (most recent call last):
  File ">>> pyshell#258", line 1, in <module>
    p = subprocess.Popen( 'Nonsense.application' )
  File "C:\Python26\lib\subprocess.py", line 621, in __init__
    errread, errwrite)
  File "C:\Python26\lib\subprocess.py", line 830, in
_execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

But when shell=True, there appears to be no way to determine if a Popen() call was successful or not.

>>> p = subprocess.Popen( 'Nonsense.application', shell=True )
>>> p
>>> subprocess.Popen object at 0x0275FF90>>>
>>> p.pid
6620
>>> p.returncode
>>>

Ideas appreciated.

Regards, Malcolm

like image 204
Malcolm Avatar asked May 18 '10 22:05

Malcolm


People also ask

How do you catch error in subprocess Popen?

You can check return code of the process using check_call() method. In case if process returned non-zero value CalledProcessError will be raised.

What does shell true do in subprocess?

On POSIX with shell=True , the shell defaults to /bin/sh . If args is a string, the string specifies the command to execute through the shell. This means that the string must be formatted exactly as it would be when typed at the shell prompt.

How can we avoid shell true in subprocess?

From the docs: args is required for all calls and should be a string, or a sequence of program arguments. Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names).

Does subprocess Popen wait for completion?

Popen Function The function should return a pointer to a stream that may be used to read from or write to the pipe while also creating a pipe between the calling application and the executed command. Immediately after starting, the Popen function returns data, and it does not wait for the subprocess to finish.


2 Answers

returncode will work, although it will be None until you've called p.poll(). poll() itself will return the error code, so you can just do

if a.poll() != 0:
    print ":("
like image 71
Michael Mrozek Avatar answered Nov 13 '22 06:11

Michael Mrozek


In the first case it fails to start, in the second - it successfully starts shell which, in turn, fails to execute the application. So your process has been properly spawned, exited and waits for you to inquire about its exit code. So, the thing is, unless your shell or environment (e.g. no memory) is utterly broken there's no way Popen itself may fail.

So, you can safely .poll() and .wait() on it to get all the sad news.

like image 22
Michael Krelin - hacker Avatar answered Nov 13 '22 05:11

Michael Krelin - hacker