os.execv
exec does not start a child - it swaps the current program for a new one, so no line after a successful exec ever runs. Available on Unix and Windows (not WASI, Android or iOS); on Unix the new program keeps the same process id, on Windows it runs as a new process.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| path | str | PathLike | yes | execv/execve/execl/execle: the program file. PATH is not searched; a relative path needs at least one slash, even on Windows. |
| file | str | PathLike | yes | The p-variants: a program name looked up in PATH (from env when one is given). |
| args | list | tuple | yes | v-variants: the full argv. args[0] is passed as the program name; it must not be empty. |
| arg0, arg1, ... | str | yes | l-variants: the same argv written as separate arguments. |
| env | Mapping[str, str] | yes | e-variants: the complete environment of the new program (it does not inherit os.environ). Keys and values must be str. |
Return value
never returns | list[str] — The exec* functions do not return - the new program takes over (errors raise OSError instead). get_exec_path() returns the list of PATH directories.
Common patterns
import os, sys sys.stdout.flush() os.execv(sys.executable, [sys.executable] + sys.argv)
import os env = {**os.environ, 'APP_MODE': 'production'} os.execvpe('gunicorn', ['gunicorn', 'app:server'], env)
import os for folder in os.get_exec_path(): print(folder)
import os pid = os.fork() if pid == 0: try: os.execlp('ls', 'ls', '-l') finally: os._exit(127) os.waitpid(pid, 0)
Examples
Pitfalls
import subprocess, sys code = 'import os, sys\ntry:\n os.execv(sys.executable, "python -V")\nexcept TypeError as e:\n print(e)' subprocess.run([sys.executable, '-c', code], capture_output=True, text=True).stdout
import shlex shlex.split('python -V')
import subprocess, sys code = 'import os, sys\ntry:\n os.execve(sys.executable, [sys.executable], {"DEBUG": 1})\nexcept TypeError as e:\n print(e)' subprocess.run([sys.executable, '-c', code], capture_output=True, text=True).stdout
settings = {'DEBUG': 1, 'WORKERS': 4} {k: str(v) for k, v in settings.items()}
When to use
- A launcher or wrapper script whose last step is to become the real program
- Restarting the current Python program in place (Unix keeps the pid)
- The exec half of a manual fork + exec
- Running a program and continuing afterwards → subprocess.run
- Windows, if anything waits for your process: the original process ends and the program continues as a new one
- Arguments with spaces on Windows: they are not quoted for you
Notes
FAQ
A successful exec replaces the process that calls it, so it cannot run inside the page. The exec functions exist on Unix and Windows (not WASI, Android or iOS), but behave differently: Unix keeps the process id, Windows starts a new process. The examples therefore only run exec calls that fail before replacing anything, inside a separate Python child.