[Tutor] Does python change subprocess based on whether it is run in the interactive shell or not

Roel Schroeven roel at roelschroeven.net
Sat Oct 29 11:51:42 EDT 2022


Nathan Smith schreef op 28/10/2022 om 13:38:
> I have some code like so:
>
>
>       p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
> stdin=subprocess.PIPE, stderr=subprocess.PIPE)
>       [stdout, stderr]=p.communicate(data)
>
>
> Where data is some data taken from io.bytesIO.read
>
> And cmd is a command for ffmpeg like so:
>
> cmd="ffmpeg/ffmpeg.exe -f wav -ac 2 -i - -f mp3 -ab 128000 - -y"
>
>
> When run in an interactive shell this works like a charm. When run in a
> script file, this breaks. At first I thought it was an issue with
> FFMPEG, but now I'm wondering if python is changing something under the
> hood?
Python doesn't magically change anything.
What do you mean by "breaks"? Do you get a traceback? What does it say?

Two points:

1) Important note though: when not using shell=True, you need to pass 
the name of the program and all arguments/options as a list with 
separate items, like so:
cmd = [
     "ffmpeg/ffmpeg.exe",
     "-f", "wav",
     "-ac", "2",
     "-i", "-",
     "-f", "mp3",
     "-ab", "128000",
     "-",
     "-y"
]
I'm actually very surprised that things worked correctly in the shell 
with cmd being one large string instead. I can't get it to work like 
that, unless I use shell=True which is best avoided.

2) What can be different between the two situations is the current 
working directory and/or executable search path (environment variable 
PATH). Check those; if needed use an absolute path, or some other way to 
unambiguously specify the path to ffmpeg.

> When running from a script, should I be using shell=True?
shell=True is to be avoided as much as possible, so no; see 
https://docs.python.org/3.10/library/subprocess.html#security-considerations 
for why.
The "shell" here does not refer to the interactive Python shell, but the 
operating system's command interpreter. As the documentation says, " The 
only time you need to specify |shell=True| on Windows is when the 
command you wish to execute is built into the shell (e.g. *dir* or 
*copy*). You do not need |shell=True| to run a batch file or 
console-based executable."
(Assuming you're on Windows because of the .exe suffix you use)


-- 

"I've come up with a set of rules that describe our reactions to technologies:
1. Anything that is in the world when you’re born is normal and ordinary and is
    just a natural part of the way the world works.
2. Anything that's invented between when you’re fifteen and thirty-five is new
    and exciting and revolutionary and you can probably get a career in it.
3. Anything invented after you're thirty-five is against the natural order of things."
         -- Douglas Adams, The Salmon of Doubt


More information about the Tutor mailing list