ZetCode

Python os.execv Function

Last modified April 11, 2025

This comprehensive guide explores Python's os.execv function, which replaces the current process with a new program. We'll cover argument passing, environment handling, and practical execution examples.

Basic Definitions

The os.execv function replaces the current process with a new program. It requires the path to the executable and an argument list.

Key parameters: path (executable file path), args (argument list). Unlike os.system, it doesn't create a new process but replaces the current one.

Basic Program Execution

This example demonstrates the simplest use of os.execv to run the Unix ls command. The current Python process will be replaced.

basic_execution.py
import os

# Path to the ls command (typically /bin/ls)
ls_path = "/bin/ls"

# Arguments for ls command
args = [ls_path, "-l", "/tmp"]

try:
    os.execv(ls_path, args)
    print("This line will never be reached")
except OSError as e:
    print(f"Execution failed: {e}")

The code replaces the Python process with ls -l /tmp. If the executable isn't found, an OSError is raised. The print statement after execv won't execute.

Note that the first argument should be the program name (convention), but the actual executable path is what matters.

Running Python Scripts

os.execv can execute other Python scripts. This example shows how to run a script with arguments, replacing the current process.

run_python_script.py
import os
import sys

# Path to Python interpreter
python_path = sys.executable

# Path to script to execute
script_path = "other_script.py"

# Arguments for the script
args = [python_path, script_path, "--verbose", "input.txt"]

try:
    os.execv(python_path, args)
except OSError as e:
    print(f"Failed to execute script: {e}")
    sys.exit(1)

This replaces the current process with a new Python process running other_script.py. The arguments include the interpreter path, script path, and script-specific arguments.

The current process memory is completely replaced by the new script's execution environment.

Executing with Environment Variables

This example shows how to modify environment variables before executing a program. The new process inherits the current environment by default.

environment_execution.py
import os

# Modify environment variables
os.environ["DEBUG"] = "1"
os.environ["LANG"] = "en_US.UTF-8"

# Path to the program
program_path = "/usr/bin/env"

# Arguments to print the environment
args = [program_path]

try:
    os.execv(program_path, args)
except OSError as e:
    print(f"Execution failed: {e}")

The example modifies environment variables before executing env which prints the current environment. The new process sees the updated vars.

Environment changes made before os.execv are visible to the new process, but changes after won't occur as the process is replaced.

Executing Shell Commands

While os.execv doesn't use a shell by default, we can explicitly execute shell commands by invoking the shell binary with our command.

shell_command.py
import os

# Path to bash shell
bash_path = "/bin/bash"

# Command to execute (with -c flag)
args = [bash_path, "-c", "echo $HOME && ls -l /tmp | wc -l"]

try:
    os.execv(bash_path, args)
except OSError as e:
    print(f"Failed to execute shell command: {e}")

This executes a shell command pipeline through bash. The -c flag makes bash execute the provided command string.

Note that shell features like variables and pipes work here because we're explicitly invoking the shell to interpret them.

Error Handling

This example demonstrates comprehensive error handling when using os.execv, including checking file existence and permissions.

error_handling.py
import os
import sys

def safe_execv(program_path, args):
    if not os.path.exists(program_path):
        raise FileNotFoundError(f"Program not found: {program_path}")
    
    if not os.access(program_path, os.X_OK):
        raise PermissionError(f"Not executable: {program_path}")
    
    try:
        os.execv(program_path, args)
    except OSError as e:
        print(f"Execution failed: {e}", file=sys.stderr)
        sys.exit(1)

# Example usage
program = "/usr/bin/whoami"
args = [program]

safe_execv(program, args)

The safe_execv function performs pre-flight checks before attempting execution. This provides better error messages than the raw call.

Note that between the checks and actual execution, the file state could change. For security-critical applications, additional measures may be needed.

Executing with Different Working Directory

This example shows how to change the working directory before executing a program. The new process inherits the current working directory.

working_directory.py
import os

# Change working directory
target_dir = "/var/log"
os.chdir(target_dir)

# Program to execute (will list /var/log contents)
program = "/bin/ls"
args = [program]

try:
    os.execv(program, args)
except OSError as e:
    print(f"Failed to execute: {e}")

The working directory is changed before executing ls, so it will list the contents of /var/log rather than the original directory.

Environment changes like working directory, open files, and signal handlers are inherited by the new process unless explicitly changed.

Security Considerations

Best Practices

Source References

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Python tutorials.