1

I was recently introduced to the useful subprocess library and its Popen and call methods to fork out processes from the python process. However, I am somewhat confused by the general rules of how to form the list which is passed as an argument to popen. The first question is, why cannot I just pass a single string, just like what I would input to a terminal, instead of separating the elements into list items?

And then, what are the general rules? As an example, if the shell command looks like

/usr/bin/env python3 script.py arg1 arg2

then how should the Popen argument list look like? Can I pass any shell command? Then where can I find the general rules to split any shell command into list items?

Della
  • 1,264
  • 2
  • 15
  • 32
  • 1
    The general rules depend on which shell you are using, but `man bash` and the [POSIX shell specification](http://pubs.opengroup.org/onlinepubs/9699919799/idx/shell.html) should give you all the information you need. – chepner Mar 08 '19 at 13:48
  • Python is perfectly capable of running Python code in a separate process without the overhead and portability issues of invoking `subprocess`. Look into `multiprocessing`. – tripleee Mar 10 '19 at 11:45

1 Answers1

0

This might be a duplicate of:

Using a Python subprocess call to invoke a Python script

you want to start a python script in a new subprocess?

Note that forking is totally differnt in Linux then it is in Windows.

generally you would pass a list of arguments like this:

p = subprocess.Popen([command, arg1, arg2,],
                     stdout=subprocess.PIPE)

where

command = "python" # or "python3"

and you can optionally get the output or handle the error:

output, error = p.communicate()

this alias must be in your PATH, otherwise you should use the full path to that binary or virtualenv...

Consider using async, if you are on Python3, but of course maybe this has no benefits for your usecase.

skidzo
  • 395
  • 3
  • 12
  • Not quite. The list argument would be `["/usr/bin/env", "python", arg1, arg2]` (assuming `arg1` and `arg2` are already `str` objects). Since the `exec*` system call used by `Popen` already does path lookup, there is no reason to use `/usr/bin/env` at all; you aren't trying to replicate the shell's shebang. Just use `python3`. – chepner Mar 08 '19 at 13:47
  • Thanks, for the correction, but that only works when you have the alias python, python3 or whatever in your PATH, right? – skidzo Mar 10 '19 at 11:11
  • An alias is only useful in an interactive shell, and by definition is not a file, and thus cannot be in your `PATH`. These complications and nuances are just another reason to avoid `subprocess` for this particular use case. You are already running the Python interpreter; why should you need to figure out how to run it again? – tripleee Mar 10 '19 at 11:48
  • @skidzo `/usr/bin/env` *also* only works when you have its argument in your `PATH`. – chepner Mar 10 '19 at 14:11