Python: subprocess call with shell=False not working

后端 未结 4 1756
孤街浪徒
孤街浪徒 2020-12-01 16:57

I am using Python script to invoke a Java virtual machine. The following command works:

subprocess.call([\"./rvm\"], shell=False)  # works
subprocess.call([\         


        
相关标签:
4条回答
  • 2020-12-01 17:01

    You need to split the commands into separate strings:

    subprocess.call(["./rvm", "xyz"], shell=False)
    

    A string will work when shell=True but you need a list of args when shell=False

    The shlex module is useful more so for more complicated commands and dealing with input but good to learn about:

    import shlex
    
    cmd = "python  foo.py"
    subprocess.call(shlex.split(cmd), shell=False)
    

    shlex tut

    0 讨论(0)
  • 2020-12-01 17:06

    If you want to use shell=True, this is legit, otherwise it would have been removed from the standard library. The documentation doesn't say to avoid it, it says:

    Executing shell commands that incorporate unsanitized input from an untrusted source makes a program vulnerable to shell injection, a serious security flaw which can result in arbitrary command execution. For this reason, the use of shell=True is strongly discouraged in cases where the command string is constructed from external input.

    But in your case you are not constructing the command from user input, your command is constant, so your code doesn't present the shell injection issue. You are in control of what the shell will execute, and if your code is not malicious per se, you are safe.

    Example of shell injection

    To explain why the shell injection is so bad, this is the example used in the documentation:

    >>> 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...
    

    Edit

    With the additional information you have provided editing the question, stick to Padraic's answer. You should use shell=True only when necessary.

    0 讨论(0)
  • 2020-12-01 17:11

    In addition to Enrico.bacis' answer, there are two ways to call programs. With shell=True, give it a full command string. With shell=False, give it a list.

    If you do shell tricks like *.jpg or 2> /dev/null, use shell=True; but in general I suggest shell=False -- it's more durable as Enrico said.

    source

    import subprocess
    subprocess.check_call(['/bin/echo', 'beer'], shell=False)
    subprocess.check_call('/bin/echo beer', shell=True)
    

    output

    beer
    beer
    
    0 讨论(0)
  • 2020-12-01 17:11

    Instead of using the filename directory, add the word python in front of it, provided that you've added python path to your environmental variables. If you're not sure, you can always rerun the python installer, once again, provided that you have a new version of python.

    Here's what I mean:

    import subprocess
    subprocess.Popen('python "C:/Path/To/File/Here.py"')
    
    0 讨论(0)
提交回复
热议问题