Python-powered shell providing superset of Python with shell primitives for cross-platform command execution and automation.
Xonsh's shell interface provides interactive command execution, pipeline management, and shell session control. The shell supports multiple backends (readline, prompt-toolkit, dumb) and provides comprehensive command processing with Python integration.
from xonsh.shell import Shell
class Shell:
"""Main shell interface for xonsh."""
def __init__(self, execer=None, ctx=None, **kwargs):
"""Initialize shell.
Parameters
----------
execer : Execer, optional
Code executer instance
ctx : dict, optional
Execution context
**kwargs
Additional shell configuration
"""
def cmdloop(self, intro=None) -> None:
"""Start the interactive command loop.
Parameters
----------
intro : str, optional
Introduction message to display
"""
def default(self, line: str) -> None:
"""Execute a line of input.
Parameters
----------
line : str
Command line to execute
"""
def precmd(self, line: str) -> str:
"""Process command before execution.
Parameters
----------
line : str
Raw command line
Returns
-------
str
Processed command line
"""
def postcmd(self, stop: bool, line: str) -> bool:
"""Process command after execution.
Parameters
----------
stop : bool
Whether to stop the command loop
line : str
Executed command line
Returns
-------
bool
Whether to continue the command loop
"""from xonsh.shells.readline_shell import ReadlineShell
class ReadlineShell(Shell):
"""Shell using Python's readline library."""
def __init__(self, **kwargs):
"""Initialize readline shell."""
def singleline(self, store_in_history=True, **kwargs) -> str:
"""Read a single line of input.
Parameters
----------
store_in_history : bool, default True
Whether to store input in history
Returns
-------
str
Input line
"""from xonsh.shells.ptk_shell import PromptToolkitShell
class PromptToolkitShell(Shell):
"""Enhanced shell using prompt-toolkit library."""
def __init__(self, **kwargs):
"""Initialize prompt-toolkit shell."""
def singleline(self, store_in_history=True, **kwargs) -> str:
"""Read a single line with enhanced features.
Parameters
----------
store_in_history : bool, default True
Whether to store in history
Returns
-------
str
Input line with syntax highlighting and completion
"""from xonsh.platform import best_shell_type
# Automatic shell selection
shell_type = best_shell_type() # Returns 'prompt_toolkit', 'readline', or 'dumb'
# Manual shell creation
from xonsh.shell import Shell
shell = Shell(shell_type='prompt_toolkit')from xonsh.built_ins import XSH
# Key shell configuration variables
env = XSH.env
env['SHELL_TYPE'] = 'prompt_toolkit' # Shell backend to use
env['XONSH_SHOW_TRACEBACK'] = True # Show Python tracebacks
env['COMPLETIONS_CONFIRM'] = True # Confirm before completing
env['COMPLETION_QUERY_LIMIT'] = 100 # Max completions to show
env['MULTILINE_PROMPT'] = ' ' # Continuation prompt
env['PROMPT'] = '{cwd} $ ' # Primary prompt formatfrom xonsh.shell import Shell
shell = Shell()
# Single command execution
shell.default("ls -la")
shell.default("echo $HOME")
shell.default("python -c 'print(2+2)'")
# Multi-line command
shell.default("""
for i in range(3):
print(f"Count: {i}")
""")from xonsh.built_ins import XSH
# Execute through XSH session
result = XSH.execer.eval("ls | wc -l")
XSH.execer.exec("MY_VAR = 'hello'")
# Execution with context
ctx = {'x': 10, 'y': 20}
result = XSH.execer.eval("x + y", ctx=ctx) # Returns 30from xonsh.procs.pipelines import run_subproc
from xonsh.procs.specs import SubprocSpec
# Create subprocess specification
spec = SubprocSpec(['ls', '-la'], captured='stdout')
result = run_subproc(spec)
# Pipeline execution
from xonsh.built_ins import subproc_captured_stdout
output = subproc_captured_stdout(['ls', '-la']) # Captured outputfrom xonsh.events import events
@events.on_transform_command
def transform_command(cmd: str) -> str:
"""Transform command before parsing.
Parameters
----------
cmd : str
Original command
Returns
-------
str
Transformed command
"""
return cmd.replace('ll', 'ls -la')
@events.on_precommand
def before_command(cmd: str) -> None:
"""Called before command execution.
Parameters
----------
cmd : str
Command to be executed
"""
print(f"Executing: {cmd}")
@events.on_postcommand
def after_command(cmd: str, rtn: int, out: str, ts: list) -> None:
"""Called after command execution.
Parameters
----------
cmd : str
Executed command
rtn : int
Return code (0 for success)
out : str or None
Command output if captured
ts : list
Timestamps [start, end]
"""
if rtn != 0:
print(f"Command failed with code {rtn}")
@events.on_command_not_found
def command_not_found(cmd: list[str]) -> None:
"""Called when command is not found.
Parameters
----------
cmd : list[str]
Command arguments that were not found
"""
print(f"Command not found: {' '.join(cmd)}")@events.on_pre_prompt_format
def before_prompt_format() -> None:
"""Called before prompt formatting."""
pass
@events.on_pre_prompt
def before_prompt() -> None:
"""Called just before showing prompt."""
pass
@events.on_post_prompt
def after_prompt() -> None:
"""Called after prompt input is received."""
passfrom xonsh.shells.base_shell import BaseShell
class CustomShell(BaseShell):
"""Custom shell implementation."""
def __init__(self, **kwargs):
super().__init__(**kwargs)
def cmdloop(self, intro=None):
"""Custom command loop implementation."""
while True:
try:
line = self.singleline()
if line.strip() == 'exit':
break
self.default(line)
except KeyboardInterrupt:
print("^C")
except EOFError:
break
def singleline(self, **kwargs) -> str:
"""Custom input implementation."""
return input(self.format_prompt())
def format_prompt(self) -> str:
"""Format custom prompt."""
return "custom> "from xonsh.built_ins import XSH
# Access shell state
shell = XSH.shell
if shell:
# Check if shell is interactive
is_interactive = hasattr(shell, 'cmdloop')
# Access shell history
if hasattr(shell, 'history'):
recent_commands = shell.history.items()
# Shell execution context
ctx = shell.ctx if hasattr(shell, 'ctx') else {}from xonsh.tools import XonshError, print_exception
try:
XSH.execer.eval("invalid_syntax }")
except SyntaxError as e:
print_exception() # Pretty-print exception
except XonshError as e:
print(f"Xonsh error: {e}")# Seamless Python integration in shell
"""
In xonsh shell:
>>> import sys
>>> sys.version
>>> len([x for x in range(10) if x % 2 == 0])
>>> $(echo "Shell command")
>>> for i in range(3):
... echo f"Hello {i}"
"""
# Programmatic integration
def run_shell_command(cmd):
"""Run shell command and return result."""
from xonsh.built_ins import subproc_captured_stdout
return subproc_captured_stdout(cmd)
result = run_shell_command(['ls', '-la'])from xonsh.procs.jobs import jobs, fg, bg, disown
# List active jobs
active_jobs = jobs()
# Foreground/background job control
fg(1) # Bring job 1 to foreground
bg(1) # Send job 1 to background
disown(1) # Disown job 1
# Job status checking
from xonsh.built_ins import XSH
if hasattr(XSH, 'all_jobs'):
for job in XSH.all_jobs:
print(f"Job {job.obj}: {job.status}")The shell interface provides the foundation for all interactive xonsh usage, supporting both simple command execution and complex Python-shell integration scenarios.
Install with Tessl CLI
npx tessl i tessl/pypi-xonsh