Python-powered shell providing superset of Python with shell primitives for cross-platform command execution and automation.
Xonsh provides seamless integration between Python and shell scripting, allowing execution of xonsh code (Python + shell syntax), subprocess management, and pipeline creation. The Execer class handles code parsing and execution, while the API modules provide clean interfaces for subprocess operations.
from xonsh.execer import Execer
class Execer:
"""Executes xonsh code in a context-aware manner."""
def __init__(self, filename: str = "<xonsh-code>",
debug_level: int = 0,
parser_args: dict = None,
scriptcache: bool = True,
cacheall: bool = False):
"""Initialize code executer.
Parameters
----------
filename : str, default "<xonsh-code>"
Name for executed code (error reporting)
debug_level : int, default 0
Debug level for parsing (0-2)
parser_args : dict, optional
Additional parser configuration
scriptcache : bool, default True
Whether to cache compiled bytecode
cacheall : bool, default False
Whether to cache all code including interactive input
"""
def parse(self, input: str, ctx: dict, mode: str = "exec",
filename: str = None, transform: bool = True) -> object:
"""Parse xonsh code with context awareness.
Parameters
----------
input : str
Code string to parse
ctx : dict
Execution context/namespace
mode : str, default "exec"
Parsing mode ("exec", "eval", "single")
filename : str, optional
Filename for error reporting
transform : bool, default True
Whether to apply context-aware transformations
Returns
-------
object
Parsed AST or None if parsing failed
"""
def eval(self, input: str, ctx: dict = None, filename: str = None) -> object:
"""Evaluate xonsh expression and return result.
Parameters
----------
input : str
Expression to evaluate
ctx : dict, optional
Execution context
filename : str, optional
Filename for error reporting
Returns
-------
object
Evaluation result
"""
def exec(self, input: str, ctx: dict = None, filename: str = None) -> None:
"""Execute xonsh code statement(s).
Parameters
----------
input : str
Code to execute
ctx : dict, optional
Execution context
filename : str, optional
Filename for error reporting
"""
# Usage examples
execer = Execer()
# Execute shell commands
execer.exec("ls -la")
execer.exec("echo 'Hello World'")
# Execute Python code
execer.exec("x = 10")
result = execer.eval("x * 2") # Returns 20
# Mixed Python and shell
execer.exec("""
import os
files = $(ls).strip().split('\n')
for f in files:
print(f"File: {f}")
""")from xonsh.built_ins import XSH
# Execute with custom context
context = {
'my_var': 'hello',
'my_func': lambda x: x.upper()
}
# Code that uses the context
code = """
result = my_func(my_var)
echo @(result) # Outputs: HELLO
"""
XSH.execer.exec(code, ctx=context)
# Access results from context
final_context = context.copy()
XSH.execer.exec("output = $(date)", ctx=final_context)
date_output = final_context['output']from xonsh.api.subprocess import run, check_call, check_output
def run(cmd: str|list[str], cwd: str = None, check: bool = False) -> object:
"""Execute subprocess with xonsh syntax.
Parameters
----------
cmd : str or list[str]
Command to execute
cwd : str, optional
Working directory for command
check : bool, default False
Whether to raise exception on non-zero exit
Returns
-------
object
Process object with returncode, stdout, stderr
"""
def check_call(cmd: str|list[str], cwd: str = None) -> int:
"""Execute subprocess, raise exception on failure.
Parameters
----------
cmd : str or list[str]
Command to execute
cwd : str, optional
Working directory
Returns
-------
int
Return code (0 on success)
Raises
------
XonshCalledProcessError
If command returns non-zero exit code
"""
def check_output(cmd: str|list[str], cwd: str = None) -> bytes:
"""Execute subprocess and return stdout.
Parameters
----------
cmd : str or list[str]
Command to execute
cwd : str, optional
Working directory
Returns
-------
bytes
Captured stdout content
Raises
------
XonshCalledProcessError
If command returns non-zero exit code
"""
# Usage examples
import tempfile
# Basic subprocess execution
result = run(['ls', '-la'])
print(f"Exit code: {result.returncode}")
# Execute in specific directory
with tempfile.TemporaryDirectory() as tmpdir:
result = run('touch test.txt', cwd=tmpdir)
# Check command success
try:
check_call(['git', 'status'])
print("Git repository detected")
except Exception:
print("Not a git repository")
# Capture command output
try:
output = check_output(['git', 'branch', '--show-current'])
branch = output.decode().strip()
print(f"Current branch: {branch}")
except Exception:
print("Could not get git branch")from xonsh.procs.specs import SubprocSpec
from xonsh.procs.pipelines import run_subproc
def create_subprocess_spec(cmd: list[str], **kwargs) -> SubprocSpec:
"""Create subprocess specification.
Parameters
----------
cmd : list[str]
Command and arguments
**kwargs
Additional subprocess options
Returns
-------
SubprocSpec
Subprocess specification object
"""
# Create and run subprocess
spec = SubprocSpec(['ls', '-la'],
captured='stdout',
stack=None)
result = run_subproc(spec)from xonsh.procs.pipelines import Pipeline
class Pipeline:
"""Manages subprocess pipelines."""
def __init__(self, specs: list[SubprocSpec]):
"""Initialize pipeline.
Parameters
----------
specs : list[SubprocSpec]
List of subprocess specifications
"""
def run(self) -> object:
"""Execute the pipeline.
Returns
-------
object
Pipeline execution result
"""
# Pipeline examples using built-in functions
from xonsh.built_ins import subproc_captured_stdout
# Simple pipeline (command | command)
output = subproc_captured_stdout(['ls', '-la'])
lines = output.strip().split('\n')
python_files = [line for line in lines if '.py' in line]
# Multi-stage pipeline simulation
def pipeline_ls_grep_wc():
"""Simulate: ls | grep .py | wc -l"""
files = subproc_captured_stdout(['ls']).strip().split('\n')
py_files = [f for f in files if '.py' in f]
return len(py_files)
count = pipeline_ls_grep_wc()from xonsh.procs.proxies import ProcProxy
# Process proxy for advanced control
def create_interactive_process(cmd: list[str]) -> ProcProxy:
"""Create interactive process proxy.
Parameters
----------
cmd : list[str]
Command to execute
Returns
-------
ProcProxy
Process proxy for interaction
"""
from xonsh.procs.specs import SubprocSpec
spec = SubprocSpec(cmd, captured=False)
return ProcProxy(spec)
# Usage with interactive commands
# proc = create_interactive_process(['python', '-i'])
# proc.communicate(input=b"print('hello')\n")from xonsh.codecache import run_script_with_cache, run_code_with_cache
def run_script_with_cache(filename: str, glb: dict = None,
loc: dict = None) -> None:
"""Execute xonsh script file with caching.
Parameters
----------
filename : str
Path to xonsh script file
glb : dict, optional
Global namespace
loc : dict, optional
Local namespace
"""
def run_code_with_cache(code: str, filename: str = "<code>",
glb: dict = None, loc: dict = None) -> None:
"""Execute xonsh code with bytecode caching.
Parameters
----------
code : str
Code string to execute
filename : str, default "<code>"
Filename for caching and error reporting
glb : dict, optional
Global namespace
loc : dict, optional
Local namespace
"""
# Execute script files
run_script_with_cache('my_script.xsh')
run_script_with_cache('/path/to/script.py', glb=globals())
# Execute code with caching
script_code = """
echo "Starting process..."
files = $(ls *.py)
echo f"Found {len(files.split())} Python files"
"""
run_code_with_cache(script_code, filename="list_files.xsh")from xonsh.built_ins import XSH
def generate_and_execute_script(template: str, **kwargs) -> object:
"""Generate and execute xonsh script from template.
Parameters
----------
template : str
Script template with {variable} placeholders
**kwargs
Variables to substitute in template
Returns
-------
object
Execution result
"""
script = template.format(**kwargs)
return XSH.execer.eval(script)
# Template-based script generation
file_template = """
import os
target_dir = "{directory}"
if os.path.exists(target_dir):
files = $(ls {directory})
echo f"Directory {target_dir} contains: {{files}}"
else:
echo f"Directory {target_dir} does not exist"
"""
result = generate_and_execute_script(file_template, directory="/tmp")from xonsh.tools import XonshError, XonshCalledProcessError
def safe_execute(cmd: str) -> tuple[bool, str]:
"""Safely execute command with error handling.
Parameters
----------
cmd : str
Command to execute
Returns
-------
tuple[bool, str]
(success, output_or_error)
"""
try:
result = XSH.execer.eval(f"$({cmd})")
return True, result
except XonshCalledProcessError as e:
return False, f"Command failed: {e}"
except XonshError as e:
return False, f"Xonsh error: {e}"
except Exception as e:
return False, f"Unexpected error: {e}"
# Usage
success, output = safe_execute("git status")
if success:
print(f"Git status: {output}")
else:
print(f"Error: {output}")from xonsh.built_ins import XSH
def conditional_execution():
"""Execute commands based on environment."""
env = XSH.env
# Platform-specific execution
if env.get('ON_WINDOWS'):
XSH.execer.exec('dir')
else:
XSH.execer.exec('ls -la')
# Conditional tool usage
if 'VIRTUAL_ENV' in env:
print("Running in virtual environment")
XSH.execer.exec('pip list')
else:
print("No virtual environment active")
# Configuration-based scripting
def load_config_and_execute():
"""Load configuration and execute based on settings."""
env = XSH.env
# Set defaults
env.setdefault('PROJECT_ROOT', '.')
env.setdefault('BUILD_TYPE', 'debug')
# Execute based on configuration
build_cmd = f"make {env['BUILD_TYPE']}"
XSH.execer.exec(f"cd {env['PROJECT_ROOT']} && {build_cmd}")from xonsh.built_ins import call_macro
def script_with_macros():
"""Integrate macros in scripting."""
# Define macro (would typically be in xonshrc)
macro_code = """
def backup_files(pattern):
files = $(find . -name @(pattern))
for f in files.split():
cp @(f) @(f + '.bak')
return f"Backed up {len(files.split())} files"
"""
XSH.execer.exec(macro_code)
# Use macro in script
result = call_macro('backup_files', '*.py')
print(result)The scripting API provides powerful tools for automating tasks, integrating shell commands with Python logic, and creating sophisticated command-line applications that leverage both Python's capabilities and shell command efficiency.
Install with Tessl CLI
npx tessl i tessl/pypi-xonsh