Python子进程调用在Mac OS X上找不到完整路径

2024-09-28 17:01:20 发布

您现在位置:Python中文网/ 问答频道 /正文

在我的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

如果我直接把它放进终端,它会工作得很好。

我错过了什么?


Tags: 脚本appforbinsh错误buildercontents
1条回答
网友
1楼 · 发布于 2024-09-28 17:01:20

默认情况下,subprocess.call不使用shell(shell=False)。因此,没有必要逃离这些空间。shell中需要空间转义(因为shell需要知道二进制文件的名称和参数)。因此,以下用途均正确(且类似):

  1. 不生成生成子进程的外壳(有利):

    from subprocess import call
    call('/Applications/BitRock InstallBuilder for Qt 8.5.2/bin/Builder.app/Contents/MacOS/installbuilder.sh')
    
  2. 或者不使用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)
    
  3. 但是,当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)
    
  4. 另一种方法是使用shell和引号:

    from subprocess import call
    call('"/Applications/BitRock InstallBuilder for Qt 8.5.2/bin/Builder.app/Contents/MacOS/installbuilder.sh"',
         shell=True)
    

我建议尽可能不要使用shell(主要是出于安全原因),但请记住,如果不使用shell,则必须将参数作为list传递给命令。

或者(没有外壳,有利的):

call(['/bin/echo', 'foo', 'bar'])

或者用贝壳

call('/bin/echo foo bar', shell=True)

(两个调用都有相同的输出(foo bar\n

相关问题 更多 >