Python subprocess.run()只运行到第一个换行符的命令



我正在调查我使用的一些软件上的一个错误,我看到python的subprocess.run()出现了意外行为。当提供一个命令字符串时,它似乎只运行该命令直到第一个换行符(在windows上(。例如:

示例1-没有换行符:

python -c "import subprocess; from subprocess import PIPE; call = subprocess.run('''echo out 1 && echo out 2''', check=True, stdout=PIPE,stderr=subprocess.PIPE,shell=True,); print(call.stdout.decode('utf-8'))"

输出:

out 1
out 2

示例2-除了命令字符串中的1个换行符之外,其他脚本相同:

python -c "import subprocess; from subprocess import PIPE; call = subprocess.run('''echo out 1
&& echo out 2''', check=True, stdout=PIPE,stderr=subprocess.PIPE,shell=True,); print(call.stdout.decode('utf-8'))"

输出:

out  1

我认为读取输出可能有问题,但我尝试在换行之前和之后写入文件,但它以前只起作用,所以我认为问题实际上是它只执行换行之前的命令。

如何使用换行符完全执行字符串?

更新:

从技术上讲,我认为以下是我需要工作的情况。上述情况在两个回波之间具有CCD_ 2。下面的情况并非如此,就好像它们是执行脚本的两行:

python -c "import subprocess; from subprocess import PIPE; call = subprocess.run('''echo out 1
echo out 2''', check=True, stdout=PIPE,stderr=subprocess.PIPE,shell=True,); print(call.stdout.decode('utf-8'))"

在Windows上它打印1行,但在Ubuntu上它打印2行。

我发现,如果将子流程设置为使用pwsh而不是cmd,它可以解决问题:

将环境变量COMSPEC设置为pwsh,而不是cmd。例如在powershell中:

$oldComSpec = $env:COMSPEC
try {
$env:COMSPEC="$(Get-Command pwsh | select -ExpandProperty Source) -NoProfile"
someScript.ps1
} finally {
$env:COMSPEC = $oldComSpec
}

到目前为止,这对我有效。

我不太清楚为什么三引号的规则在这里不起作用,但用适当的引号盖住断开的字符串似乎已经解决了这个问题。也许python-c不处理传递的字符串中的三引号,因为字符串本身被认为是三引号?只是我的猜测,希望这能有所帮助。

python -c "import subprocess; from subprocess import PIPE; call = subprocess.run('echo out 1'
'&& echo out 2', check=True, stdout=PIPE,stderr=subprocess.PIPE,shell=True,); print(call.stdout.decode('utf-8'))"

最新更新