Python:subprocess调用时shell=False无效
我正在用Python脚本来调用Java虚拟机。下面这个命令可以正常运行:
subprocess.call(["./rvm"], shell=False) # works
subprocess.call(["./rvm xyz"], shell=True) # works
但是,
subprocess.call(["./rvm xyz"], shell=False) # not working
这个命令就不行了。Python的文档建议尽量避免使用 shell=True
。
4 个回答
0
不要直接使用文件名的目录,而是在前面加上 python
这个词,前提是你已经把 Python 的路径添加到了你的环境变量里。如果你不确定是否添加了,可以重新运行 Python 的安装程序,只要你有一个新的 Python 版本就可以了。
我说的意思是:
import subprocess
subprocess.Popen('python "C:/Path/To/File/Here.py"')
4
除了Enrico.bacis的回答,还有两种方式可以调用程序。使用 shell=True
时,你需要给出一个完整的命令字符串。而使用 shell=False
时,你需要提供一个列表。
如果你要使用一些特殊的命令,比如 *.jpg
或者 2> /dev/null
,就用 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
8
如果你想使用 shell=True
,这是可以的,否则它早就会从标准库中被删除了。文档里并没有说要避免使用它,而是提到:
执行包含来自不可信来源的未经处理输入的 shell 命令,会让程序容易受到 shell 注入攻击,这是一种严重的安全漏洞,可能导致任意命令被执行。因此,在 命令字符串是由外部输入构建的 情况下,强烈不建议使用
shell=True
。
但在你的情况下,你并不是从用户输入构建命令,你的命令是固定的,所以你的代码并不存在 shell 注入 的问题。你可以控制 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...
编辑
根据你提供的额外信息,编辑问题时请遵循 Padraic 的回答。你应该仅在必要时使用 shell=True
。