Python:使用shell = False的子进程调用不起作用

Tan*_*nay 12 python shell subprocess

我正在使用Python脚本来调用Java虚拟机.以下命令有效:

subprocess.call(["./rvm"], shell=False)  # works
subprocess.call(["./rvm xyz"], shell=True) # works
Run Code Online (Sandbox Code Playgroud)

但,

subprocess.call(["./rvm xyz"], shell=False) # not working
Run Code Online (Sandbox Code Playgroud)

不起作用.要避免的Python文档建议shell=True.

Pad*_*ham 26

您需要将命令拆分为单独的字符串:

subprocess.call(["./rvm", "xyz"], shell=False)
Run Code Online (Sandbox Code Playgroud)

一个字符串可以工作,shell=True但是你需要一个args列表shell=False

对于更复杂的命令和处理输入,shlex模块更有用,但有助于了解:

import shlex

cmd = "python  foo.py"
subprocess.call(shlex.split(cmd), shell=False)
Run Code Online (Sandbox Code Playgroud)

shut tut

  • @Tommy,通常最好避免使用 shell=True,如果您完全控制正在运行的内容,则使用它并不是世界末日,但是几乎可以使用 shell=True 执行的所有操作都可以使用 shell =假的。当您至少在 unix 上传递 args 列表时,第一个 arg 是要执行的命令,其余的是该命令的 args,如果您使用 shell=True,则必须完全按照将其传递给的方式传递该命令外壳,shell=True 可以允许的示例 https://docs.python.org/2/library/subprocess.html#frequently-used-arguments (2认同)

enr*_*cis 6

如果你想使用shell=True,这是合法的,否则它将被从标准库中删除.文档没有说避免它,它:

执行包含来自不受信任源的未经过处理的输入的shell命令会使程序容易受到shell注入,这是一个严重的安全漏洞,可能导致任意命令执行.因此,在从外部输入构造命令字符串的shell=True情况下,强烈建议不要使用.

但是在您的情况下,您没有从用户输入构造命令,您的命令是常量,因此您的代码不会出现shell注入问题.您可以控制shell将执行的操作,如果您的代码本身不是恶意的,那么您就是安全的.

壳注射的例子

为了解释为什么shell注入如此糟糕,这是文档中使用的示例:

>>> 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...
Run Code Online (Sandbox Code Playgroud)

编辑

通过提供编辑问题的其他信息,请坚持使用Padraic的答案.您应该shell=True只在必要时使用.