When to use Shell = True for Python subprocess module

It seems that whenever I try to use the Python subprocess module, I find that I still don't understand some things. I am currently trying to join 3 mp4 files from a Python module.

When i tried

z ='MP4Box -cat test_0.mp4 -cat test_1.mp4 -cat test_2.mp4 -new test_012d.mp4'
subprocess.Popen(z,shell=True)

      

It all worked.

When i tried

z = ['MP4Box', '-cat test_0.mp4', '-cat test_1.mp4', '-cat test_2.mp4', '-new test_012d.mp4']
subprocess.Popen(z,shell=False)

      

I got the following error:

Option -cat test_0.mp4 unknown. Please check usage

      

I thought shell=False

I just needed to provide a list in which the first item was the executable that I wanted to run, and each subsequent item was an argument for that executable. Am I wrong in this belief, or is there a correct way to create the command I wanted to use?

Also, are there any usage rules Shell=True

in the .Popen subprocess? So far, all I really know (?) Is "don't do this - you can expose your code for shell attacks". Why shell=False

avoid this problem? Is there ever an actual advantage to using "Shell = True"?

+3


source to share


2 answers


If a shell True

, the specified command will be executed through the shell. This can be useful if you are using Python primarily for the advanced control flow that it offers for most system shells, and still want convenient access to other shell features such as shells, wildcards, environment variable expansion, and extension ~

to the users home directory.

When is shell=True

it dangerous?

If we execute shell commands that may include unanitized input from an untrusted source , it makes the vulnerable program a shell , a serious security flaw that could lead to arbitrary command execution. For this reason, use is shell=True

strongly discouraged in cases where the command line is built from external input



Eg. (Taken from the docs )

>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / #
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly..

      

+9


source


You must specify each individual argument as one of the list items:

z = ['MP4Box', '-cat', 'test_0.mp4', '-cat', 'test_1.mp4', '-cat', 'test_2.mp4', '-new', 'test_012d.mp4']
subprocess.Popen(z,shell=False)

      



This is usually what you want to do, because you don't need to escape special shell characters in filenames.

+3


source







All Articles