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

时间:2014-08-23 19:35:23

标签: python shell subprocess

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

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

但是,

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

不起作用。 Python documentation建议避免shell=True

4 个答案:

答案 0 :(得分:23)

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

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

字符串在shell=True时有用,但在shell=False

时需要一个args列表

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

import shlex

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

shlex tut

答案 1 :(得分:5)

如果您想使用shell=True,这是合法的,否则它将从标准库中删除。文档并没有说要避免它,says

  

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

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

壳注射的例子

为了解释为什么shell注入如此糟糕,这是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...

修改

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

答案 2 :(得分:4)

除了Enrico.bacis'回答,有两种方法可以调用程序。使用shell=True,给它一个完整的命令字符串。使用shell=False,列出一个列表。

如果您使用*.jpg2> /dev/null等shell技巧,请使用shell=True;但总的来说,我建议shell=False - 它比Enrico说的更持久。

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

输出

beer
beer

答案 3 :(得分:0)

如果您已经为您的环境变量添加了python路径,则不要使用文件名目录,而是在其前面添加单词python。如果您不确定,只要您拥有新版本的python,就可以再次重新运行python安装程序。

这就是我的意思:

import subprocess
subprocess.Popen('python "C:/Path/To/File/Here.py"')