A robust Python module for executing shell commands with advanced features including input/output file tracking, asynchronous execution, logging, and validation.
- Robust command execution: Both synchronous and asynchronous shell command execution
- File validation: Automatic validation of input and output files/directories
- Comprehensive logging: Optional command logging to file with execution history
- Process management: Track and manage multiple asynchronous processes
- Error handling: Detailed error reporting and validation
- Flexible configuration: Customizable shell executable, output suppression, and more
- Zero dependencies: No external dependencies required
pip install -U shoper
from shoper import ShellOperator
# Simple command execution
sh = ShellOperator()
sh.run('ls -la')
from shoper import ShellOperator
# Execute commands with logging
sh = ShellOperator(log_txt='commands.log', quiet=False)
sh.run('echo "Hello World"')
from shoper import ShellOperator
sh = ShellOperator()
# Validate input files exist and output files are created
sh.run(
args='sort input.txt > output.txt',
input_files_or_dirs=['input.txt'],
output_files_or_dirs=['output.txt']
)
from shoper import ShellOperator
sh = ShellOperator(log_txt='workflow.log')
# Generate random numbers
sh.run(
args=[
'echo ${RANDOM} | tee random0.txt',
'echo ${RANDOM} | tee random1.txt',
'echo ${RANDOM} | tee random2.txt'
],
output_files_or_dirs=['random0.txt', 'random1.txt', 'random2.txt']
)
# Sort the generated numbers
sh.run(
args='sort random[012].txt | tee sorted.txt',
input_files_or_dirs=['random0.txt', 'random1.txt', 'random2.txt'],
output_files_or_dirs='sorted.txt'
)
from shoper import ShellOperator
sh = ShellOperator()
# Start multiple long-running processes
sh.run('sleep 10 && echo "Task 1 done"', asynchronous=True)
sh.run('sleep 15 && echo "Task 2 done"', asynchronous=True)
sh.run('sleep 5 && echo "Task 3 done"', asynchronous=True)
# Wait for all processes to complete
sh.wait()
print("All tasks completed!")
from shoper import ShellOperator
# Advanced configuration
sh = ShellOperator(
log_txt='detailed.log',
quiet=True, # Suppress command output
print_command=False, # Don't print commands before execution
executable='/bin/zsh', # Use zsh instead of bash
clear_log_txt=True # Clear log file on initialization
)
sh.run('complex_command --with-args')
from shoper import ShellOperator
sh = ShellOperator()
try:
sh.run(
args='process_data input.csv',
input_files_or_dirs=['input.csv'],
output_files_or_dirs=['output.csv'],
remove_previous_outputs=True # Clean up before execution
)
except Exception as e:
print(f"Command failed: {e}")
The ShellOperator
class supports the following configuration parameters:
Parameter | Type | Default | Description |
---|---|---|---|
log_txt |
str , Path or None |
None |
Path to log file for command output |
quiet |
bool |
False |
Suppress command output to stdout |
clear_log_txt |
bool |
False |
Clear log file on initialization |
print_command |
bool |
True |
Print commands before execution |
executable |
str |
/bin/bash |
Shell executable to use |
Execute shell commands with extensive configuration options.
Parameters:
args
: Command string or list of commands to executeinput_files_or_dirs
: Files/directories that must exist before executionoutput_files_or_dirs
: Files/directories expected after executionoutput_validator
: Optional callable for custom output validationcwd
: Working directory for command executionprompt
: Custom prompt string for command loggingasynchronous
: Execute command asynchronously (default:False
)remove_if_failed
: Remove output files if command fails (default:True
)remove_previous_outputs
: Remove output files before execution (default:False
)skip_if_exist
: Skip execution if output files exist (default:True
)- Additional subprocess parameters supported
Wait for all asynchronous processes to complete.
- Python 3.10 or higher
- POSIX-compatible operating system (Linux, macOS)
- No external dependencies
git clone https://github.com/dceoy/shoper.git
cd shoper
pip install -e .
# Linting
ruff check .
ruff check . --fix
# Type checking
pyright
# Run unit tests
uv run pytest
Testing is performed via pytest with comprehensive unit tests and GitHub Actions for CI/CD.
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
This project is licensed under the MIT License - see the LICENSE file for details.
Daichi Narushima, Ph.D. (@dceoy)