[英]Python subprocess call can't find full path on Mac OS X
In my Python script, this line: 在我的Python脚本中,这一行:
call("/Applications/BitRock\\ InstallBuilder\\ for\\ Qt\\ 8.5.2/bin/Builder.app/Contents/MacOS/installbuilder.sh")
will fail every time with the error OSError: [Errno 2] No such file or directory
每次都会失败,并显示错误OSError: [Errno 2] No such file or directory
However, if I write out the result of that string: 但是,如果我写出该字符串的结果:
sys.stdout.write("/Applications/BitRock\\ InstallBuilder\\ for\\ Qt\\ 8.5.2/bin/Builder.app/Contents/MacOS/installbuilder.sh")
I get: 我得到:
/Applications/BitRock\ InstallBuilder\ for\ Qt\ 8.5.2/bin/Builder.app/Contents/MacOS/installbuilder.sh
If I put that directly into the terminal, it works perfect. 如果我直接将其放入终端,则效果很好。
What am I missing? 我想念什么?
By default subprocess.call
uses no shell ( shell=False
). 默认情况下, subprocess.call
使用任何shell( shell=False
)。 Therefore, there's no need to escape the spaces. 因此,无需逃脱空间。 The space escaping is needed in shells (because shells need to know what's the binary's name and what the arguments). shell需要空格转义(因为shell需要知道二进制文件的名称和参数)。 Therefore the following uses are all correct (and similar): 因此,以下所有用法都是正确的(和相似的):
Without spawning a shell that spawns the subprocess (favorable): 在不产生产生子进程的外壳的情况下(有利):
from subprocess import call call('/Applications/BitRock InstallBuilder for Qt 8.5.2/bin/Builder.app/Contents/MacOS/installbuilder.sh')
or again without shell (explicit shell=False
and the usage of an argument list) 或再次不使用shell(显式shell=False
和参数列表的用法)
from subprocess import call call(['/Applications/BitRock InstallBuilder for Qt 8.5.2/bin/Builder.app/Contents/MacOS/installbuilder.sh'], shell=False)
But when subprocess
is told to first of all swawn shell which then spawns the subprocess itself, the spaces have to be escaped, because it's a shell command: 但是,当首先告诉subprocess
进程所有swawn shell之后又产生子进程本身时,必须转义空格,因为这是一个shell命令:
from subprocess import call call('/Applications/BitRock\\\\ InstallBuilder\\\\ for\\\\ Qt 8.5.2/bin/Builder.app/Contents/MacOS/installbuilder.sh', shell=True)
An alternative would be to use a shell and quotes: 一种替代方法是使用外壳和引号:
from subprocess import call call('"/Applications/BitRock InstallBuilder for Qt 8.5.2/bin/Builder.app/Contents/MacOS/installbuilder.sh"', shell=True)
I'd recommend not to use a shell whenever possible (mostly for security reasons), remember though you have to pass the arguments to the command as a list
if you're not using a shell. 我建议尽可能不要使用shell(主要出于安全原因),请记住,如果不使用shell,则必须将参数作为list
传递给命令。
Either (without shell, favourable): 任一种(无壳,有利):
call(['/bin/echo', 'foo', 'bar'])
or with a shell 或带壳
call('/bin/echo foo bar', shell=True)
(both calls have the same output ( foo bar\\n
) (两个调用的输出都相同( foo bar\\n
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.