Python source file preprocessor/interpreter and subprocess pipe manager to enable running in-line bash/shell code during python runtime.
#!/usr/bin/env python
from pysh import pysh
pysh()
#$@ echo "Pysh activated"
stdout = ""#$ echo "This is standard out"
print(stdout)
##@!python print("Python through a pysh pype")
Use #$ flagged directives to signify shell code to be piped through a subprocess.
When you run pysh() execution stops, and the source file will be processed with regex to extract and replace the code blocks with a subprocess wrapper, and then the source file itself is run through it.
# Script your system in parallel with your python code execution
# Do anything you can in bash e.g.
build_service()
#$ cd ~/hosted/myservice && docker compose up
aggregate_assets()
crf = "23"
in_file = "/path/in.mp4"
out_file = "/path/out.mp4"
fmpg_result = ""#$ ffmpeg -i {$in_file$} \
#$ -crf {$crf$} -o {$out_file$} \
#$ && rm {$in_file$}
process_assets(process_fmpg_stdout(fmpg_result))
print("Process complete")
From PyPI:
pip3 install pyshpype
Git to local folder:
pip3 install -e "git+https://github.com/blipk/pysh.git#egg=pysh"
#!/usr/bin/python
from pysh import pysh
pysh()
#$ echo "pysh activated" >> .pysh
# Use the @ flag to always print(stdout) to main sys.stdout
#$@ echo "hello from bash"
# This is a python comment
#$@ ls . # shell eol comment
##$ sudo rm -rf / # disable pysh line with pysh comment
# Capture stdout from the shell subprocess
stout = ""#$ echo "I'm actually a bytes string"
print(stdout.decode("UTF-8"))
# Pass any python variable thats in scope to the pysh script
my_var = "hello"
stdout = ""#$ echo "{$myvar$}"
# run external script with double $
#$$ my_script.sh
# optionally pass arguments to it
#$$ argumentative_script.sh arg1 arg2
# Use the ! flag to change the shell that interprets the script
# must support -c command_strings or filepath if external $$
#$!sh echo "simple"
#$!perl oysters.pl
#$$@!bash printscript.sh
# Multiple flags/features
stdout = ""#$@!python import time
#$ print("The time and date", time.asctime())
# Use the % flag to catch errors,
# otherwise they will be printed but not raised
try:
result = ""#$$% tests/dinger/notfoundscript.sh "argone"
except SystemExit as e:
print("Error", e)
if __name__ == "main":
print("Before the above script blocks are run")
# Pysh runs code in blocks that are executed in-place
# Block 0
#$ cd $HOME
stdout_block1 = ""#$ echo "first block is multiline"
#$ echo "line1"
#$ echo "line2"
# The last script block won't be run
sys.exit(1)
stdout_block2 == ""#$ echo "Second"
#$ echo "Block"
# run pysh manually
from pysh import Pysh
source_file = __file__
pysher = Pysh(source_file)
blocks = pysher.findblocks()
# Run a a single block
blocks[0].run() # Not run in-place, no stdout. Silent.
# Run script block again, and print stdout with label for block
blocks[0].runp()
# Run all wanted blocks sequentially at this point,
# and print their stdout with labels
run_blocks = [block.runp() for block in blocks
if "/root" in block.srcs]
# Start the python interpreter with pysh on source_file
# This is the same as running pysh(__file__)
pysher.shyp()
#$ echo "pysh enabled"
# Switch to another source file and run it through pysh
pysher.pysh(__file__)
# Equivalent to above
pysher.updatesrc(__file__)
pysher.pysh()
# Get information about the script blocks at runtime
t_block = pysher.blocks[0]
print(t_block.hasrun, t_block.returncode)
print(t_block.srcs, "\n--\n", t_block.stdout)