Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:shell=False的子进程调用不工作_Python_Shell_Subprocess - Fatal编程技术网

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

Python:shell=False的子进程调用不工作,python,shell,subprocess,Python,Shell,Subprocess,我正在使用Python脚本调用Java虚拟机。以下命令起作用: subprocess.call(["./rvm"], shell=False) # works subprocess.call(["./rvm xyz"], shell=True) # works 但是, 不起作用。建议避免使用shell=True如果您想使用shell=True,这是合法的,否则它将从标准库中删除。文档并没有说要避免它,而是说: 执行包含来自不受信任源的未初始化输入的shell命令会使程序容易受到shell注入

我正在使用Python脚本调用Java虚拟机。以下命令起作用:

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


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

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

执行包含来自不受信任源的未初始化输入的shell命令会使程序容易受到shell注入的攻击,这是一个严重的安全缺陷,可能导致任意命令执行。因此,在命令字符串是从外部输入构建的情况下,强烈反对使用
shell=True

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

外壳注入示例 为了解释shell注入为何如此糟糕,以下是中使用的示例:

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

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

如果您使用shell技巧,如
*.jpg
2>/dev/null
,请使用
shell=True
;但总的来说,我建议
shell=False
——正如恩里科所说,它更耐用

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

subprocess.call(["./rvm", "xyz"], shell=False)
shell=True
时,字符串将起作用,但当
shell=False

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

import shlex

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

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

我的意思是:

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

这个答案也解决了我的问题。您能否详细说明为什么“当shell=True时字符串可以工作,但当shell=False时您需要参数列表”是正确的?我听说有输入时,
shell=True
是非常危险的,所以我试图避免它。@Tommy,一般来说,shell=True是最好避免的,如果你完全控制你正在运行的东西,使用它并不是世界末日,但是几乎所有你能用shell=True做的事情你都可以用shell=False做。当您至少在unix上传递一个参数列表时,第一个参数是要执行的命令,其余的是该命令的参数,如果您使用shell=True,则必须像将命令传递给shell一样传递该命令,shell=True的示例可能允许更改一个参数的结构,这是一个奇怪的API(这里是arg列表或命令)基于另一个布尔参数(Shell是否为True)。这应该在子流程中进行内部处理,以便在不考虑
Shell
的情况下传递相同的参数。
beer
beer
subprocess.call(["./rvm", "xyz"], shell=False)
import shlex

cmd = "python  foo.py"
subprocess.call(shlex.split(cmd), shell=False)
import subprocess
subprocess.Popen('python "C:/Path/To/File/Here.py"')