[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