os.spawnv
The spawn family = fork + exec in one call. spawnl/spawnle/spawnv/spawnve and P_WAIT/P_NOWAIT/P_NOWAITO exist on Unix and Windows; the PATH-searching spawnlp/spawnlpe/spawnvp/spawnvpe are not available on Windows; P_DETACH and P_OVERLAY are Windows only; posix_spawn, posix_spawnp and the POSIX_SPAWN_* constants are Unix only.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| mode | int | yes | P_WAIT (wait, return the exit code), P_NOWAIT / P_NOWAITO (return at once with the pid), Windows only: P_DETACH (no console) and P_OVERLAY (replace the current process, like exec). |
| path | str | PathLike | yes | The program. Only the p-variants search PATH; the others need an absolute or relative path. |
| args | list | tuple | yes | v-variants: the argv, starting with the program name (not empty). l-variants pass the same items as separate arguments. |
| env | Mapping[str, str] | yes | e-variants: the complete environment of the new process; keys and values must be str. |
| file_actions | sequence of tuples | no (None) | posix_spawn: fd operations done in the child before exec - (POSIX_SPAWN_OPEN, fd, path, flags, mode), (POSIX_SPAWN_CLOSE, fd), (POSIX_SPAWN_DUP2, fd, new_fd), (POSIX_SPAWN_CLOSEFROM, fd). |
Return value
int — spawn* with P_WAIT: the exit code, or -signal if a signal killed it (Unix). With P_NOWAIT: the process id (the process handle on Windows). posix_spawn/posix_spawnp: the child pid.
Common patterns
import os os.spawnlp(os.P_WAIT, 'cp', 'cp', 'index.html', '/dev/null') L = ['cp', 'index.html', '/dev/null'] os.spawnvpe(os.P_WAIT, 'cp', L, os.environ)
import os, sys pid = os.spawnv(os.P_NOWAIT, sys.executable, [sys.executable, 'worker.py']) # ... do other work ... _, status = os.waitpid(pid, 0) exit_code = os.waitstatus_to_exitcode(status)
import os actions = [(os.POSIX_SPAWN_OPEN, 1, 'log.txt', os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o644)] pid = os.posix_spawnp('ls', ['ls', '-l'], os.environ, file_actions=actions) os.waitpid(pid, 0)
import subprocess, sys exit_code = subprocess.run([sys.executable, 'worker.py']).returncode proc = subprocess.Popen([sys.executable, 'worker.py']) proc.wait()
Examples
Pitfalls
' '.join(['-c', 'raise SystemExit(4)'])
import subprocess subprocess.list2cmdline(['-c', 'raise SystemExit(4)'])
import os, sys rc = os.spawnv(os.P_NOWAIT, sys.executable, [sys.executable, '-c', 'raise(SystemExit(7))']) os.waitpid(rc, 0) rc == 7
import os, sys pid = os.spawnv(os.P_NOWAIT, sys.executable, [sys.executable, '-c', 'raise(SystemExit(7))']) _, status = os.waitpid(pid, 0) os.waitstatus_to_exitcode(status) == 7
When to use
- Porting old code that already uses spawn*
- posix_spawn: a fast fork-free start of a program on Unix with simple fd setup
- New code → subprocess.run / subprocess.Popen (the docs recommend it)
- Arguments with spaces on Windows → subprocess, which quotes them
- spawnle / spawnve on Windows → the docs call them not thread-safe there; use subprocess
Notes
FAQ
Starting real processes cannot run in the page, and the family is split by platform: spawnl/spawnv/spawnle/spawnve work on Unix and Windows, the PATH-searching p-variants are not available on Windows, P_DETACH/P_OVERLAY are Windows only and posix_spawn is Unix only. The examples use only the parts that behave the same on Windows and Linux, with a Python child.