shellsafe
Run shell commands safely using Python 3.14 template strings. Values can never turn into commands.
from shellsafe import run
message = get_user_input() # "fix; rm -rf ~"
run(t"git commit -m {message}")
# argv: ["git", "commit", "-m", "fix; rm -rf ~"]
# one command; the scary text is just an argument
Why this package exists
Python 3.14 added template strings (PEP 750). Now Python keeps your fixed text and your values separate at the language level.
Shell commands are the first place people want to use this. That is because f-strings inside shell commands have caused real security bugs for ten years:
subprocess.run(f"git commit -m {message}", shell=True)
# if message = "fix; rm -rf ~" -> two commands run. The second one is bad.
Python planned to solve this officially (PEP 787), but that plan was postponed. So today there is no standard way to run shell commands safely with templates. This package fills that gap.
Install
pip install shellsafe
Needs Python 3.14 or newer.
How to use
Run a command. Your values always stay one argument each:
from shellsafe import run
run(t"mkdir {path}")
run(t"docker build -t {tag} .", check=True, timeout=300)
Get the output as text:
from shellsafe import capture
res = capture(t"grep {pattern} {file}")
print(res.stdout, res.returncode)
Need pipes? Works on Linux and macOS. Your values are quoted safely first:
from shellsafe import shx
shx(t"cat {file} | wc -l")
Want to see exactly what will run?
from shellsafe import plan
print(plan(t"git commit -m {message}"))
# argv: ["git","commit","-m","fix; rm -rf ~"]
Safety rules
| Case | What happens |
|---|---|
| Any value you pass | becomes one argument, exactly as given |
| Value used as the program name | error: program names must be written as fixed text |
| Shell features on Windows | error: we cannot make Windows safe this way, so we say no |
| RAW() misuse | error: one value only, used as-is, no nesting |
RAW(...) marks content you have already made safe by hand. It is loud and easy
to find in code review, so trust is never hidden.
Limits
- Shell features (pipes, redirections) work on Linux and macOS only. Windows supports plain commands only.
run()refuses templates that contain shell metacharacters. Useshx()for those.- Byte values are rejected. Decode them first.
- We keep your command safe to build and run. Testing what your command does is still your job.
Needs
- Python 3.14 or newer
- Linux, macOS, Windows (pipes work on Linux and macOS only)
More
- Source and issues: github.com/rahulXs/shellsafe
- Want to help? See CONTRIBUTING.md in the repository.
License: MIT
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 shellsafe-0.2.0.tar.gz.
File metadata
- Download URL: shellsafe-0.2.0.tar.gz
- Upload date:
- Size: 15.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e59b4e40757c2b3c20dd295c3cc778eb728bc13228cf16a39e1e1196e2a64384
|
|
| MD5 |
0c4558cb42de487585eb3c86731fc1ee
|
|
| BLAKE2b-256 |
b9b63a5d68b0e7a992dad693c3148be8c8eb4cff5049328310306bdd2789e0b1
|
Provenance
The following attestation bundles were made for shellsafe-0.2.0.tar.gz:
Publisher:
release.yml on rahulXs/shellsafe
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
shellsafe-0.2.0.tar.gz -
Subject digest:
e59b4e40757c2b3c20dd295c3cc778eb728bc13228cf16a39e1e1196e2a64384 - Sigstore transparency entry: 2615715326
- Sigstore integration time:
-
Permalink:
rahulXs/shellsafe@c42376624a4e1e8b8469a9b48d5aceccba37b39d -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/rahulXs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c42376624a4e1e8b8469a9b48d5aceccba37b39d -
Trigger Event:
push
-
Statement type:
File details
Details for the file shellsafe-0.2.0-py3-none-any.whl.
File metadata
- Download URL: shellsafe-0.2.0-py3-none-any.whl
- Upload date:
- Size: 11.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc5e353160e0fe16be949858550ad658dd70b56aceae5a7f5423bcb3d6a0f42e
|
|
| MD5 |
17129a9bfe7be65ab13f32d43655b1ae
|
|
| BLAKE2b-256 |
b599447168f5dcdfc9ae4059d5f9740f25af4c92fb047cd91ec5bf19a5b7197f
|
Provenance
The following attestation bundles were made for shellsafe-0.2.0-py3-none-any.whl:
Publisher:
release.yml on rahulXs/shellsafe
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
shellsafe-0.2.0-py3-none-any.whl -
Subject digest:
bc5e353160e0fe16be949858550ad658dd70b56aceae5a7f5423bcb3d6a0f42e - Sigstore transparency entry: 2615715374
- Sigstore integration time:
-
Permalink:
rahulXs/shellsafe@c42376624a4e1e8b8469a9b48d5aceccba37b39d -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/rahulXs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c42376624a4e1e8b8469a9b48d5aceccba37b39d -
Trigger Event:
push
-
Statement type: