{"id":6621,"library":"executor","title":"Executor: Programmer friendly subprocess wrapper","description":"The `executor` package is a simple wrapper for Python's `subprocess` module, designed to simplify handling external commands on UNIX systems. It provides an object-oriented interface with proper argument escaping and error checking. Features include support for local commands, remote commands over SSH, execution within chroots, and concurrent command execution through command pools. The library's latest version is 23.2, released in November 2020, with an irregular release cadence.","status":"active","version":"23.2","language":"python","source_language":"en","source_url":"https://github.com/xolox/python-executor","tags":["subprocess","process management","shell","ssh","chroot","concurrency","unix"],"install":[{"cmd":"pip install executor","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"note":"The primary function for simple command execution is usually imported directly.","wrong":"import executor; executor.execute()","symbol":"execute","correct":"from executor import execute"},{"note":"Used for more advanced, asynchronous, or pre-configured command execution.","symbol":"ExternalCommand","correct":"from executor import ExternalCommand"},{"note":"For executing commands concurrently on multiple remote hosts via SSH.","symbol":"foreach","correct":"from executor.ssh.client import foreach"}],"quickstart":{"code":"from executor import execute\nimport os\n\n# Run a simple command and check its success\nprint(f\"'true' command success: {execute('true')}\")\nprint(f\"'false' command success (without check): {execute('false', check=False)}\")\n\n# Provide input to a command and capture its output\noutput = execute('tr a-z A-Z', input='Hello Python Executor\\n', capture=True)\nprint(f\"Transformed output: {output.strip()}\")\n\n# Example of running a command that fails, demonstrating default error handling\ntry:\n    execute('non_existent_command')\nexcept Exception as e:\n    print(f\"Caught expected error for non-existent command: {e}\")","lang":"python","description":"This quickstart demonstrates how to run basic commands, handle their success/failure, provide standard input, and capture standard output using the `execute` function."},"warnings":[{"fix":"For complex or asynchronous command execution, migrate from direct `execute()` calls to using `ExternalCommand` instances, calling `start()` and `wait()` as needed. Simple synchronous calls to `execute()` remain compatible.","message":"The `executor` library underwent a significant interface change from version 1.x to 2.x. In 1.x, `execute()` was the sole interface. In 2.x+, the `ExternalCommand` class was introduced for more flexible and asynchronous operations, with `execute()` becoming a wrapper around it. Code written for 1.x using only `execute()` for complex scenarios might need refactoring to leverage `ExternalCommand` in 2.x+.","severity":"breaking","affected_versions":"<2.0.0"},{"fix":"Verify functionality on target non-UNIX platforms or consider alternative libraries if cross-platform compatibility is critical for all features. For basic subprocess execution, it might work, but advanced features are UNIX-specific.","message":"The `executor` package is explicitly designed for and tested on \"UNIX systems.\" While it might function on other platforms to some extent, full compatibility and all features (like chroot or schroot integration) are not guaranteed on non-UNIX environments (e.g., Windows).","severity":"gotcha","affected_versions":"All versions"},{"fix":"If a non-zero exit code is expected and should not raise an exception, pass `check=False` to the `execute()` function (e.g., `execute('false', check=False)`). The function will then return `False` for failure and `True` for success.","message":"By default, the `execute()` function raises an `ExternalCommandFailed` exception if the external command exits with a non-zero status code. This is a robust error-checking mechanism but can be unexpected if you intend to handle non-zero exit codes as part of normal program flow.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For asynchronous execution, instantiate `ExternalCommand` (e.g., `cmd = ExternalCommand(['long_running_script'])`), call `cmd.start()`, and later `cmd.wait()` to retrieve results, or poll its status.","message":"The primary `execute()` function is synchronous and will block the Python interpreter until the external command completes. For long-running commands or to achieve non-blocking execution, you must use the `ExternalCommand` class directly, which provides `start()` for asynchronous initiation and `wait()` to block only when results are needed.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Review code that relies on implicit `command` requirement or attempts to modify the `command` property directly. While this change generally improves flexibility, older code might rely on the prior, stricter behavior or expect `command` to be immutable after initialization.","message":"In `executor` version 14.0, the behavior of the `command` property changed. It became valid to set `input` and `shell` options without explicitly providing a `command` argument (which was previously mandatory). Additionally, the `command` property became mutable, allowing it to be changed using normal attribute assignment or reset with `del`.","severity":"breaking","affected_versions":"<14.0.0"}],"env_vars":null,"search_vec":"'2020':71 '23.2':67 'argument':36 'cadenc':76 'check':40 'chroot':53,82 'command':23,46,48,56,59 'concurr':55,83 'design':18 'error':39 'escap':37 'execut':51,57 'executor':1,7 'extern':22 'featur':41 'friend':3 'handl':21 'includ':42 'interfac':33 'irregular':74 'latest':64 'librari':62 'local':45 'manag':79 'modul':17 'novemb':70 'object':31 'object-ori':30 'orient':32 'packag':8 'pool':60 'process':78 'programm':2 'proper':35 'provid':28 'python':14 'releas':68,75 'remot':47 'shell':80 'simpl':11 'simplifi':20 'ssh':50,81 'subprocess':4,16,77 'support':43 'system':26 'unix':25,84 'version':65 'within':52 'wrapper':5,12","created_at":"2026-04-15T18:35:46.701120+00:00","updated_at":"2026-04-16T14:53:11.820134+00:00","problems":[{"fix":"Catch the `ExternalCommandFailed` exception to handle command failures gracefully. You can access the command's output or error streams from the exception object to diagnose the issue. Alternatively, set `check=False` when calling `execute()` if you don't want non-zero exit codes to raise an exception, though this is generally not recommended for robust error handling.","cause":"This error occurs when an external command executed by the `executor` package exits with a non-zero status code, indicating a failure in the command itself. By default, `executor` checks the exit status and raises this exception for any non-zero code.","error":"executor.ExternalCommandFailed: External command failed with exit ..."},{"fix":"Verify the correct spelling of the command and ensure it is installed and available in the system's PATH. For remote commands, ensure the command exists on the remote host. You can also specify the full path to the executable to bypass PATH lookups.","cause":"This error is raised when the external command specified for execution cannot be found in the system's PATH. This can happen if the command is misspelled, not installed, or not accessible from the environment where `executor` is running.","error":"executor.CommandNotFound: External command not found: ..."},{"fix":"Install the `executor` package using pip: `pip install executor`. Ensure that you are running your script in the Python environment where the package was installed.","cause":"This error occurs when the Python interpreter cannot find the `executor` package. This typically happens if the package was not installed correctly or if the Python environment where the code is being run does not have `executor` installed.","error":"ModuleNotFoundError: No module named 'executor'"},{"fix":"Handle the `RemoteCommandFailed` exception. Inspect the output from the remote command (usually available through the exception object) to understand why it failed. Ensure the command works correctly when executed directly on the remote host via SSH.","cause":"Similar to `ExternalCommandFailed`, this specific error indicates that a command executed on a remote host via SSH using `executor.ssh.client` returned a non-zero exit status, signaling a failure in the remote command's execution.","error":"executor.ssh.client.RemoteCommandFailed: Remote command failed with exit ..."}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"23.2","cli_name":"","cli_version":null,"type":"library","homepage":"https://executor.readthedocs.io","github":null,"docs":null,"changelog":null,"pypi":"https://pypi.org/project/executor/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["devops","http-networking"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-06-28","next_check":"2026-07-28","install_tag":null}}