I am calling different processes with the subprocess
module. However, I have a question.
In the following codes:
callProcess = subprocess.Popen(['ls', '-l'], shell=True)
and
callProcess = subprocess.Popen(['ls', '-l']) # without shell
Both work. After reading the docs, I came to know that shell=True
means executing the code through the shell. So that means in absence, the process is directly started.
So what should I prefer for my case - I need to run a process and get its output. What benefit do I have from calling it from within the shell or outside of it.
By default, running subprocess. Popen with shell=True uses /bin/sh as the shell. If you want to change the shell to /bin/bash , set the executable keyword argument to /bin/bash .
The subprocess module defines one class, Popen and a few wrapper functions that use that class. The constructor for Popen takes arguments to set up the new process so the parent can communicate with it via pipes. It provides all of the functionality of the other modules and functions it replaces, and more.
To capture the output of the subprocess. run method, use an additional argument named “capture_output=True”. You can individually access stdout and stderr values by using “output. stdout” and “output.
That said, an important piece of advice comes from os. system docs, which says: The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function.
The benefit of not calling via the shell is that you are not invoking a 'mystery program.' On POSIX, the environment variable SHELL
controls which binary is invoked as the "shell." On Windows, there is no bourne shell descendent, only cmd.exe.
So invoking the shell invokes a program of the user's choosing and is platform-dependent. Generally speaking, avoid invocations via the shell.
Invoking via the shell does allow you to expand environment variables and file globs according to the shell's usual mechanism. On POSIX systems, the shell expands file globs to a list of files. On Windows, a file glob (e.g., "*.*") is not expanded by the shell, anyway (but environment variables on a command line are expanded by cmd.exe).
If you think you want environment variable expansions and file globs, research the ILS
attacks of 1992-ish on network services which performed subprogram invocations via the shell. Examples include the various sendmail
backdoors involving ILS
.
In summary, use shell=False
.
>>> import subprocess >>> subprocess.call('echo $HOME') Traceback (most recent call last): ... OSError: [Errno 2] No such file or directory >>> >>> subprocess.call('echo $HOME', shell=True) /user/khong 0
Setting the shell argument to a true value causes subprocess to spawn an intermediate shell process, and tell it to run the command. In other words, using an intermediate shell means that variables, glob patterns, and other special shell features in the command string are processed before the command is run. Here, in the example, $HOME was processed before the echo command. Actually, this is the case of command with shell expansion while the command ls -l considered as a simple command.
source: Subprocess Module
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With