Subprocess debugging. Call call

I have successfully used subprocess.Popen in the past when I wrapped binary files with a python script to format arguments / settings, etc.

The development of the nth wrapper, I did as usual ... but nothing happens.

Here is a little code:

 print command p = subprocess.Popen(command, shell = True) result = p.communicate()[0] print vars(p) return result 

And here is the conclusion:

 /usr/bin/sh /tmp/run/launch.sh {'_child_created': True, 'returncode': 0, 'stdout': None, 'stdin': None, 'pid': 21650, 'stderr': None, 'universal_newlines': False} 

As you can see, the goal is to create a shell script, configure everything that I need, and then execute it. I would prefer to use real python code, but unfortunately launch.sh calls third-party shell scripts that I don't want to try to replicate (although I have already insisted on python api for over a year now).

The problem is that:

  • the shell script is not executed (it should start the process and display some little things)
  • python exception not thrown
  • nothing is displayed in the p object, indicating an error

I tried check_call without any success ...

I am at a loss as to what I should do, and would be very happy if someone could point out my mistake or direct me to resolve ...

EDIT:

  • Trying to run this on Linux (sh)
  • a shell is needed to substitute variables in scripts called

EDIT 2:

Following the suggestion of badp , I changed the code and added

 subprocess.Popen('ps', shell = True).communicate() 

Right after the line p = ... that creates the process, here is the output:

 /usr/bin/sh /tmp/run/launch.sh PID TTY TIME CMD 29978 pts/0 00:00:01 zsh 1178 pts/0 00:00:01 python 1180 pts/0 00:00:00 sh <defunct> 1181 pts/0 00:00:00 ps None 

Apparently, the process is starting (although <defunct> ), and it should also be noted that I have a slight problem with passing parameters to ...

Thanks.

+4
source share
2 answers

I finally found the answer to my question thanks to badp and its debugging suggestions.

On the python page on the subprocess module :

The executable file argument indicates the executable program. This is very rarely necessary: ​​usually the executable program is specified by the args argument. If shell=True , the executable argument indicates which shell to use. On Unix, the default shell is /bin/sh . On Windows, the default shell is specified by the COMSPEC environment variable. The only reason you need to specify shell=True on Windows is where the command you want to execute is really built into the shell, for example dir , copy . You do not need shell=True to run the batch file or to run the console-based executable.

Since I am on Linux and using shell=True , my command actually provides a list of arguments that should be executed by the executable, which defaults to /bin/sh . Thus, the full command is executed: /bin/sh /usr/bin/sh /tmp/run/launch.sh ... which does not work so well.

And I had to use either:

 subprocess.Popen('/tmp/run/launch.sh', shell=True) 

or

 subprocess.Popen('/tmp/run/launch.sh', executable = '/usr/bin/sh', shell=True) 

It is difficult that shell=True will actually change the default executable for Linux only ...

+2
source

Try the following:

 p = subprocess.Popen(command, shell = True, #is this even needed? stdin = subprocess.PIPE, stdout = subprocess.PIPE, # stderr = subprocess.STDOUT #uncomment if reqd ) 

Tested to work with Windows using the ping command. This allows you to communicate , which can help you figure out why the script is not running in the first place :)

+2
source

Source: https://habr.com/ru/post/1300397/


All Articles