Skip to main content

shellsafe

Safe shell commands via Python 3.14 template strings. Injection-proof by construction.

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

The dominant pattern in scripts and automation is still this:

subprocess.run(f"git commit -m {message}", shell=True)   # injection waiting to happen

Python 3.14 template strings (t"...") separate static text from interpolated values. shellsafe turns that structure into argv lists where interpolated values are always data, never commands. When you genuinely need pipes, shell mode quotes every value with POSIX rules first.

Install

pip install shellsafe

Requires Python 3.14+ (template strings).

Usage

Run a command. Interpolated values are always single arguments:

from shellsafe import run

run(t"mkdir {path}")
run(t"docker build -t {tag} .", check=True, timeout=300)

Capture output as text:

from shellsafe import capture

res = capture(t"grep {pattern} {file}")
print(res.stdout, res.returncode)

Pipes and redirections on POSIX (values are quoted with shlex.quote first):

from shellsafe import shx

shx(t"cat {file} | wc -l")

Inspect exactly what will execute:

from shellsafe import plan  # lower-level: render without running

print(plan(t"git commit -m {message}"))
# argv: ["git","commit","-m","fix; rm -rf ~"]

What it refuses

Case Behavior
Interpolation as the executable error: the command comes from static text only
Shell route on Windows error: cmd.exe quoting cannot be made injection-safe; use argv mode
RAW misuse error: one argument, verbatim, nesting refused

RAW("...") / RAW(["a", "b"]) is the single explicit trust boundary for pre-quoted content. Every use site is greppable.

Limits

  • Windows: interpolated shell routes are refused rather than approximated; argv-mode commands work fully.
  • Bytes interpolations are rejected: decode explicitly first.
  • Runtime behavior after import is your test suite's job, same trust model as calling subprocess yourself.

Contributing

Issues and PRs welcome. Security reports go privately to the maintainer, never through public issues.

Requirements

  • CPython >= 3.14 (uses template strings from PEP 750)
  • Linux, macOS, Windows (Windows supports argv mode; POSIX-only shell mode)

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

shellsafe-0.1.0.tar.gz (14.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shellsafe-0.1.0-py3-none-any.whl (11.9 kB view details)

Uploaded Python 3

File details

Details for the file shellsafe-0.1.0.tar.gz.

File metadata

  • Download URL: shellsafe-0.1.0.tar.gz
  • Upload date:
  • Size: 14.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for shellsafe-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ca3629ad9b5f604ce1c6703616c2036e09395e2779ea05cfedc9f9a85b00fe07
MD5 d17c48ec7496e90bbf66f6f55a05e55d
BLAKE2b-256 7d816a077e2f471109b1149add46607b216ee2ebf43e7307d3b6a07693e8bf83

See more details on using hashes here.

Provenance

The following attestation bundles were made for shellsafe-0.1.0.tar.gz:

Publisher: release.yml on rahulXs/shellsafe

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file shellsafe-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: shellsafe-0.1.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

Hashes for shellsafe-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9679d1193444a554840cf3920eb9efc6e9fb4492d443dbb95fa6aff54b1492b7
MD5 fa5f73307e9de10cbee4ca7c3cbdb8c5
BLAKE2b-256 4410cc52ccad9b49a8f63c9e3234dd179193453a69ea4933785a4b01f9e46f4f

See more details on using hashes here.

Provenance

The following attestation bundles were made for shellsafe-0.1.0-py3-none-any.whl:

Publisher: release.yml on rahulXs/shellsafe

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.0

2 files

0.1.1

2 files

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page