Python subprocess replacement that allows calling system commands as Python functions
—
Enhanced command wrappers that provide optimized defaults and specialized functionality for common tools. The contrib system offers pre-configured versions of popular commands with better defaults and additional features.
Enhanced git command with optimized settings for programmatic usage.
@contrib("git")
def git(orig):
"""
Git command optimized for programmatic usage.
Returns:
Command: Git command with TTY output disabled for cleaner programmatic usage
"""Usage examples:
import sh
# Use contrib git for cleaner output
git = sh.contrib.git
result = git("status", "--porcelain")
print("Modified files:", result.strip())
# Compare with regular git (may have TTY formatting)
regular_git = sh.git
git_output = regular_git("log", "--oneline", "-n", "5")
# Contrib git works better for parsing
commits = git("log", "--format=%H %s", "-n", "10").strip().split('\n')
for commit in commits:
hash_part, message = commit.split(' ', 1)
print(f"Commit: {hash_part[:8]} - {message}")Pre-configured bash command for executing shell scripts and commands.
@contrib("bash")
def bash(orig):
"""
Bash command pre-configured with -c flag for script execution.
Returns:
Command: Bash command ready for script execution
"""Usage examples:
import sh
# Execute bash commands and scripts
bash = sh.contrib.bash
result = bash("echo 'Hello from bash'; ls -la | wc -l")
print("Bash output:", result)
# Execute complex shell pipelines
pipeline_result = bash("ps aux | grep python | wc -l")
python_processes = int(pipeline_result.strip())
print(f"Python processes running: {python_processes}")
# Execute multi-line bash scripts
script = '''
for i in {1..5}; do
echo "Count: $i"
done
'''
bash(script)Enhanced sudo command with automatic password prompting and password parameter support.
@contrib("sudo")
def sudo(orig):
"""
Sudo command with enhanced password handling.
Features:
- Automatic password prompting using getpass
- Password parameter support
- Uses -S flag for stdin password input
Returns:
Command: Enhanced sudo command with password handling
"""Usage examples:
import sh
import getpass
# Interactive password prompting (secure)
sudo = sh.contrib.sudo
sudo("apt", "update") # Will prompt for password securely
# Programmatic password (use carefully)
password = getpass.getpass("Enter sudo password: ")
sudo("systemctl", "restart", "nginx", password=password)
# File operations requiring sudo
sudo("chown", "www-data:www-data", "/var/www/html/uploads/")
sudo("chmod", "755", "/var/www/html/")
# System administration tasks
result = sudo("systemctl", "status", "apache2")
if "active (running)" in result:
print("Apache is running")
else:
print("Apache is not running")Advanced SSH command with automatic password handling and interactive session support.
@contrib("ssh")
def ssh(orig):
"""
SSH command with enhanced interactive capabilities.
Features:
- Automatic password authentication
- Interactive session management
- Login success detection
- Session content tracking
Returns:
Command: Enhanced SSH command with interactive features
"""Usage examples:
import sh
# Note: SSH contrib is primarily for interactive use
# For basic SSH commands, regular sh.ssh may be sufficient
ssh = sh.contrib.ssh
# Interactive SSH session (advanced usage)
# This is primarily used for complex interactive scenarios
# Most users should use regular sh.ssh for simple commands
# Example of remote command execution
try:
result = sh.ssh("user@remote-server", "uptime")
print("Remote uptime:", result.strip())
except sh.ErrorReturnCode as e:
print("SSH failed:", e)
# For file transfers, consider using sh.scp or sh.rsync
sh.scp("local_file.txt", "user@remote:/tmp/")
sh.rsync("-av", "local_dir/", "user@remote:backup/")Extend the contrib system with your own enhanced command wrappers.
import sh
# Example: Enhanced docker command with common defaults
@sh.contrib("docker")
def docker(orig):
"""Docker command with common defaults."""
# Add common flags and settings
cmd = orig.bake("--rm") # Always remove containers after exit
return cmd
# Example: Enhanced curl with better defaults
@sh.contrib("curl")
def curl(orig):
"""Curl with better defaults for API usage."""
cmd = orig.bake(
"-s", # Silent mode
"-L", # Follow redirects
"-f", # Fail on HTTP errors
"--max-time", "30" # 30 second timeout
)
return cmd
# Usage
docker = sh.contrib.docker
curl = sh.contrib.curl
# These now have the enhanced defaults
container_output = docker("run", "ubuntu", "echo", "hello")
api_response = curl("https://api.example.com/status")Multiple ways to access and use contrib commands in your applications.
import sh
# Method 1: Direct access
git_contrib = sh.contrib.git
result = git_contrib("status")
# Method 2: Import pattern
from sh.contrib import git, sudo, bash
git_status = git("status", "--porcelain")
sudo("systemctl", "restart", "nginx")
bash_result = bash("echo $HOME; pwd")
# Method 3: Dynamic access
command_name = "git"
contrib_cmd = getattr(sh.contrib, command_name)
output = contrib_cmd("log", "--oneline", "-n", "5")
# Check available contrib commands
available_contribs = [cmd for cmd in dir(sh.contrib) if not cmd.startswith('_')]
print("Available contrib commands:", available_contribs)class Contrib(ModuleType):
"""
Module type for contrib command system.
Provides decorator interface for creating enhanced command wrappers.
"""
@classmethod
def __call__(cls, name: str):
"""
Decorator for creating contrib command wrappers.
Parameters:
- name: str = name of the command to enhance
Returns:
callable: Decorator function for command enhancement
"""Install with Tessl CLI
npx tessl i tessl/pypi-sh