Continuous shell process
Project description
Install
pip install shell_proc
Run
Run a series of commands with results.
from shell_proc import Shell
with Shell() as sh:
sh('cd ..')
if sh.is_windows():
cmd = sh('dir')
else:
cmd = sh('ls')
# cmd (Command) Attributes: cmd, exit_code, stdout, stderr
print(cmd.stdout)
Run a series of terminal commands.
import sys
from shell_proc import Shell
with Shell(stdout=sys.stdout, stderr=sys.stderr) as sh:
sh.run('mkdir storage')
sh('cd storage') # Same as sh.run()
sh('echo Hello World! > hello.txt')
if sh.is_windows():
sh('python -m venv ./winvenv')
sh('call ./winvenv/Scripts/activate.bat')
else:
pwd = sh('pwd')
sh('cd ~')
sh('python3 -m venv ./lxvenv')
sh('source ./lxvenv/bin/activate')
sh('cd {}'.format(pwd.stdout))
sh('pip install requests')
sh('pip list')
table = '|{:_<20}|{:_<20}|{:_<20}|{:_<50}|'
print(table.format('', '', '', '').replace('|', '_'))
print(table.format("Exit Code", "Has Error", "Has Ouput", "Command").replace('_', ' '))
print(table.format('', '', '', ''))
for cmd in sh.history:
print(table.format(cmd.exit_code, cmd.has_error(), cmd.has_output(), cmd.cmd).replace('_', ' '))
print(table.format('', '', '', '').replace('|', '_'))
Run without blocking every command
import sys
import time
from shell_proc import Shell
with Shell(stdout=sys.stdout, stderr=sys.stderr, blocking=False, wait_on_exit=True) as sh:
sh.run('mkdir storage')
sh('cd storage') # Same as sh.run()
sh('echo Hello World! > hello.txt')
if sh.is_windows():
sh('python -m venv ./winvenv')
sh('call ./winvenv/Scripts/activate.bat')
else:
pwd = sh('pwd')
sh('cd ~')
sh('python3 -m venv ./lxvenv')
sh('source ./lxvenv/bin/activate')
sh('cd {}'.format(pwd.stdout))
sh('pip install requests')
sh('pip list')
print('---------- At exit (shows non-blocking until exit) ----------')
time.sleep(1)
print('1 Second has passed', 'Running:', sh.current_command)
time.sleep(1)
print('2 Seconds have passed', 'Running:', sh.current_command)
time.sleep(1)
print('3 Seconds have passed', 'Running:', sh.current_command)
sh.wait() # Wait for all commands to finish
Manually call commands and check results.
import io
import sys
from shell_proc import Shell
# Initialize and run tasks
sh = Shell('mkdir storage',
'cd storage',
'echo Hello World! > hello.txt',
stderr=io.StringIO())
# Manually run tasks
if sh.is_windows():
sh('python -m venv ./winvenv')
sh('call ./winvenv/Scripts/activate.bat')
else:
pwd = sh('pwd')
sh('cd ~')
sh('python3 -m venv ./lxvenv')
sh('source ./lxvenv/bin/activate')
sh('cd {}'.format(pwd.stdout))
# Not exactly success. If True no output was printed to stderr. Stderr could also be warning like need to update pip
results = sh.run('pip install requests')
print("***** Successful install: ", results.exit_code == 0)
if results.exit_code != 0:
sh.stderr.seek(0) # Move to start of io.StringIO()
err = sh.stderr.read() # All text collected into stderr from subprocess stderr
print(err, file=sys.stderr)
# sh.print_stderr() # Also available
sh.stdout = io.StringIO() # Start saving output for new tasks
results = sh('pip list')
print('***** Output Printed\n', results.stdout)
sh('pip -V')
print('pip -V =>', sh.last_command.stdout)
print('All collected stdout')
sh.stdout.seek(0) # Move to start of io.StringIO()
print(sh.stdout.read(), end='', flush=True) # Print all read data
# Should close when finished to stop threads from reading stdout and stderr subprocess.PIPE
# (will close automatically eventually)
sh.close()
io.StringIO() Help
Below are several functions to read data from stdout and io.StringIO()
def read_io(fp):
"""Return all of the human readable text from the io object."""
try:
if fp.seekable():
fp.seek(0)
out = fp.read()
if not isinstance(out, str):
out = out.decode('utf-8')
return out
except:
return ''
def clear_io(fp):
"""Try to clear the stdout"""
text = read_io(fp)
try:
fp.truncate(0)
except:
pass
return text
def print_io(fp, end='\n', file=None, flush=True):
"""Print and clear the collected io."""
if file is None:
file = sys.stdout
print(clear_io(fp), file=file, flush=True)
Run Python
Added support to call python in a subprocess
from shell_proc import Shell
with Shell(python_call='python3') as sh:
sh.python('-c',
'import os',
'print("My PID:", os.getpid())')
Run Parallel
Added support to run parallel subprocesses
import sys
import time
from shell_proc import Shell, python_args
with Shell(stdout=sys.stdout, stderr=sys.stderr) as sh:
p = sh.parallel(*(python_args('-c',
'import os',
'import time',
"print('My ID:', {id}, 'My PID:', os.getpid(), time.time())".format(id=i)) for i in range(10)))
sh.wait() # or p.wait()
print('finished parallel')
time.sleep(1)
tasks = []
for i in range(10):
if i == 3:
t = python_args('-c',
'import os',
'import time',
'time.sleep(1)',
"print('My ID:', {id}, 'My PID:', os.getpid(), time.time())".format(id=i))
else:
t = python_args('-c',
'import os',
'import time',
"print('My ID:', {id}, 'My PID:', os.getpid(), time.time())".format(id=i))
tasks.append(t)
p = sh.parallel(*tasks)
p.wait()
print('finished parallel')
time.sleep(1)
with sh.parallel() as p:
for i in range(10):
if i == 3:
p.python('-c',
'import os',
'import time',
'time.sleep(1)',
"print('My ID:', {id}, 'My PID:', os.getpid(), time.time())".format(id=i))
else:
p.python('-c',
'import os',
'import time',
"print('My ID:', {id}, 'My PID:', os.getpid(), time.time())".format(id=i))
# p.wait() on exit context
print('finished parallel')
Use Pipe
The pipe operator can be used with Command objects to take a completed command stdout and submit the text into a new commands stdin.
import sys
from shell_proc import Shell, ShellExit, shell_args
with Shell(stdout=sys.stdout, stderr=sys.stderr) as sh:
# One step
results = sh('dir') | 'find "run"' # Hard to tell where find output starts
# Two Steps
cmd = sh('dir')
results = cmd | 'find "run"'
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file shell_proc-1.2.2.tar.gz.
File metadata
- Download URL: shell_proc-1.2.2.tar.gz
- Upload date:
- Size: 14.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
517d58731e61ae073e9028658b04bd46648a2b097af8c69b89e3244289d47226
|
|
| MD5 |
15f9fb350c869fcab2cc7fec41a6d954
|
|
| BLAKE2b-256 |
d3b01325f15f89a48a25df84bcff5f0d2809c09d609dd6b18e30c6732d919ab4
|
File details
Details for the file shell_proc-1.2.2-py3-none-any.whl.
File metadata
- Download URL: shell_proc-1.2.2-py3-none-any.whl
- Upload date:
- Size: 32.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31977dec7adcba873c3d0ba13788384782d815f122fc20898c2ea8156567bb3d
|
|
| MD5 |
cd760298c01e3d80d61541a081f4b5b2
|
|
| BLAKE2b-256 |
68594b7810981dda9d4df18b537969c4ac800f404a3f139ba5b490babc0ae0d7
|