skip to Main Content

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.

2

Answers


  1. Chosen as BEST ANSWER

    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.


  2. 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'))"
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search