I'm looking into a bug on some software I use and I'm seeing unexpected behavior from python's subprocess.run()
. When a command string is provided, it seems to only run the command up until the first newline (on windows). For example:
Example 1 - No newline:
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'))"
Output:
out 1
out 2
Example 2 - Same script except 1 newline in the command string:
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'))"
Output:
out 1
I thought it might be an issue with reading the output, but I tried writing to a file before and after the newline, and it only worked before, so I think indeed the problem is that it only executes commands up to the newline.
How do I fully execute strings with newlines in them?
UPDATE:
Technically, I think below is the case that I need to work. The above case has &&
between the two echoes. The case below does not, as if they were two lines of an executing script:
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'))"
On Windows this prints 1 line, but on Ubuntu it prints 2.
CodePudding user response:
I discovered if you set subprocess to use pwsh instead of cmd it fixes the problem:
Set the environment variable COMSPEC
to pwsh
instead of cmd
. For example in powershell:
$oldComSpec = $env:COMSPEC
try {
$env:COMSPEC="$(Get-Command pwsh | select -ExpandProperty Source) -NoProfile"
someScript.ps1
} finally {
$env:COMSPEC = $oldComSpec
}
So far this is working for me.
CodePudding user response:
I'm not exactly sure why the rules of triple quotes didn't work here, but capping that broken string with the appropriate quotes seems to have fixed the issue. Maybe python -c doesn't handle triple quotes inside the string being passed because the string itself is considered in the same way triple quotes are? just my guess, hope this helps.
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'))"