README
Warning
WIP. Until v1.0.0 is released, API is subject to drastic changes.
Run safe and cross-platform bash commands using Python 3.14's t-strings
Uses brush for a cross-platform bash implementation.
from tshu import sh
await sh(t"uv add tshu")
Installation
uv add tshu
Usage
from tshu import sh
Run a bash command.
Always use a t-string, regular strings are not allowed to prevent accidental usage of f-strings.
await sh(t"cat /usr/share/dict/words | wc -l")
Run a bash command with user input
You still need to quote substitutions to prevent word-splitting. Word-splitting is a feature, not a vuln.
Substitutions use variables to prevent shell injection. These temporary variables are not accessible by child programs as they are not exported and have random names.
await sh(t'cat "{__file__}" | wc -l')
Exit code and check
By default, awaiting a command returns the exit code. tshu.CommandError is raised
when a command returns a non-zero exit code. To disable this behaviour, either
pass check=False
to sh
or set sh.check = False
to disable checking globally.
Suppress command output
Either pass quiet=True
or set sh.quiet = True
to suppress output globally.
Change working directory
Either pass cwd=...
or set sh.cwd = "..."
. You can use pathlib.Path
.
Set environment variables
Either modify os.environ
or pass env={}
. These are exported, so accessible to
child programs, use substitutions to pass user input.
Pass standard input
input can be string or bytes.
assert await sh(t"wc -l", input="1\n2\n3\n").json() == 3
Capture the stdout, stderr of a program
result = await sh(t"help").output()
result.returncode
result.stdout
result.stderr
Get standard output directly
Use .text()
to directly get the output as string (utf-8 encoded).
contents = await sh(t"cat file.txt").text()
Get standard output directly as bytes
contents = await sh(t"cat file.bin").bytes()
Get standard output parsed as JSON
data = await sh(t"cat file.json").json()