Python subprocess.popen 与子进程交互时失败

Python subprocess.popen fails when interacting with the subprocess

我有一个 Xamarin 应用程序的 python 构建脚本,我需要根据语言环境将其编译成不同的 ipa 和 apk。

脚本操作 info.plist 和 Android 清单中的必要值,然后使用 subprocess.popen 构建每个版本以调用 xbuild。或者至少应该是这样。

问题是当我无论如何与子进程交互时(基本上我需要等到它完成才能开始更改下一个版本的值)

这个有效:

    build_path = os.path.dirname(os.path.realpath(__file__))
    ipa_path = "/path/to/my.ipa"

    cmd = '/Library/Frameworks/Mono.framework/Versions/4.6.2/Commands/xbuild /p:Configuration="Release" /p:Platform="iPhone" /p:IpaPackageDir="%s" /t:Build %s/MyApp/iOS/MyApp.iOS.csproj' % (ipa_path, build_path)

    subprocess.Popen(cmd, env=os.environ, shell=True)

然而,这将导致 python 脚本与构建并行继续。

如果我这样做:

    subprocess.Popen(cmd, env=os.environ, shell=True).wait()

Xbuild 失败并显示以下错误消息:

    Build FAILED.
    Errors:

    /Users/sune/dev/MyApp/iOS/MyApp.iOS.csproj: error :
    /Users/sune/dev/MyApp/iOS/MyApp.iOS.csproj: There is an unclosed literal string.
    Line 2434, position 56.

它会在调用后几毫秒内失败,而通常构建过程需要几分钟

subprocess.popen 的任何其他 shorthand 方法,例如 .call、.check_call,以及 subprocess.poll 和 subprocess.communicate 的基础操作会导致相同的结果发生错误。

真正奇怪的是,即使调用 time.sleep 也会引发同样的错误:

    subprocess.Popen(cmd, env=os.environ, shell=True)

    time.sleep(2)

我不明白,因为据我了解,我也应该能够做这样的事情:

    shell = subprocess.Popen(cmd, env=os.environ, shell=True)

    while shell.poll() is None:
        time.sleep(2)

    print "done"

基本上实现与调用 shell.wait()

相同的效果

编辑:使用命令列表而不是字符串

如果我像这样使用命令列表和 shell=False

      cmd = [
        '/Library/Frameworks/Mono.framework/Versions/4.6.2/Commands/xbuild',
        '/p:Configuration="Release"',
        '/p:Platform="iPhone"',
        '/p:IpaPackageDir="%s' % ipa_path,
        '/t:Build %s/MyApp/iOS/MyApp.iOS.csproj' % build_path

    ]

    subprocess.Popen(cmd, env=os.environ, shell=False)

那么结果是这样的:

    MSBUILD: error MSBUILD0003: Please specify the project or solution file to build, as none was found in the current directory.

非常感谢任何意见。我在这里用头撞墙。

我坚信这是不可能的。肯定是subprocess模块​​实现方式的不足

xbuild 在构建期间生成多个子进程,如果轮询状态 python 中的子进程将发现其中一个具有非零 return 状态并停止执行一个或多个导致构建失败的 xbuild 子进程的数量,如所述。

我最终使用 bash 脚本进行编译并使用 python 操作 xml 文件等