无法使用命令行运行的命令调用子进程。

3
以下命令可以在CLI中正常使用:
bash <(curl -Ls https://coverage.codacy.com/get.sh) report -r /path/coverage.xml

当我将相同的命令传递给 subprocess 时,如果 shell=False,我会收到以下错误信息:
FileNotFoundError: [Errno 2] No such file or directory: 'bash <(curl -Ls https://coverage.codacy.com/get.sh) report -r /path/coverage.xml'

当使用shell=True时,我收到了这个错误:

/bin/sh: -c: line 0: syntax error near unexpected token `('

对我来说,当shell为False时,整个命令似乎被视为一个路径,但我不明白为什么subprocess认为在shell=True时存在语法错误。
我该如何从Python中使此命令工作?

你应该将下载和执行脚本作为两个单独的步骤。使用子进程时,输入重定向的工作方式不同。 - OneCricketeer
此外,当仅使用字符串时,它是可执行文件的路径(因此您会收到“FileNotFoundError”),而不应该是您想要运行的完整命令。您需要使用列表来运行带有参数的命令。 - OneCricketeer
2
正如错误信息所示,shell=True使用的是/bin/sh,它需要是一个符合POSIX标准的shell(显然在您的系统上实际上是以POSIX模式运行的bash)。进程替换是ksh/bash扩展,它不是有效的POSIX。 - dave_thompson_085
虽然链接的重复内容最直接,但您可能还会发现使用Python的Popen()进行bash风格的进程替换也很有趣——展示了如何在没有shell=True的情况下获得相同的效果。 - Charles Duffy
1个回答

1

您尝试运行的命令需要使用Bash,但是subprocess默认使用sh,除非您另有说明。

p = subprocess.run(
    "bash <(curl -Ls https://coverage.codacy.com/get.sh) report -r /path/coverage.xml",
    shell=True, check=True, text=True,
    executable="/bin/bash")

这里的代码不必要地将bash作为其子进程运行,但是它可以立即完成工作。

更高效的解决方案应该避免额外的shell,但也许您应该重构代码,用一个简单的本地Python web客户端替换curl


1
也许将内部的 bash 更改为 source 可以避免额外的进程? - Charles Duffy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接