在我的Python脚本中,这一行:
call("/Applications/BitRock\\ InstallBuilder\\ for\\ Qt\\ 8.5.2/bin/Builder.app/Contents/MacOS/installbuilder.sh")
每次出现错误OSError: [Errno 2] No such file or directory
时,都会失败
但是,如果我写出该字符串的结果:
sys.stdout.write("/Applications/BitRock\\ InstallBuilder\\ for\\ Qt\\ 8.5.2/bin/Builder.app/Contents/MacOS/installbuilder.sh")
我明白了:
/Applications/BitRock\ InstallBuilder\ for\ Qt\ 8.5.2/bin/Builder.app/Contents/MacOS/installbuilder.sh
如果我把它直接放入终端,那就完美了。
我错过了什么?
答案 0 :(得分:7)
默认情况下,subprocess.call
不使用shell(shell=False
)。因此,没有必要逃离空间。 shell中需要空间转义(因为shell需要知道二进制文件的名称和参数是什么)。因此,以下用途都是正确的(和类似的):
不产生产生子进程的shell(有利):
from subprocess import call
call('/Applications/BitRock InstallBuilder for Qt 8.5.2/bin/Builder.app/Contents/MacOS/installbuilder.sh')
或再次没有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)
但是当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)
另一种方法是使用shell并引用:
from subprocess import call
call('"/Applications/BitRock InstallBuilder for Qt 8.5.2/bin/Builder.app/Contents/MacOS/installbuilder.sh"',
shell=True)
我建议尽可能不使用shell(主要是出于安全考虑),请记住,如果您不使用“list
”,则必须将参数传递给命令call(['/bin/echo', 'foo', 'bar'])
外壳
(无壳,有利):
call('/bin/echo foo bar', shell=True)
或使用shell
foo bar\n
(两个调用具有相同的输出({{1}})