Skip to main content

Virtual terminal with shell-like commands over a pluggable filesystem.

Project description

termish 📺

Virtual terminal with shell-like commands over a pluggable filesystem.

Parses and executes shell scripts (pipelines, redirects, semicolons) against any object that implements the FileSystem protocol. Zero runtime dependencies. Pure Python.

Features

  • Shell parser -- pipes, redirects (>, >>, <), semicolons, quoted strings, line continuation
  • 30 builtins -- ls, cat, grep, find, sed, tr, sort, uniq, cut, wc, diff, tar, gzip, zip, jq, xargs, basename, dirname, ...
  • jq engine -- built-in jq filter parser and evaluator (field access, pipes, functions, conditionals)
  • Pluggable filesystem -- FileSystem is a typing.Protocol; any object with the right methods works
  • MemoryFS included -- in-memory filesystem for testing and lightweight use

Install

pip install termish

Quick example

from termish import execute, MemoryFS

fs = MemoryFS()

execute("mkdir -p src", fs)
execute("echo 'def main(): pass' > src/app.py", fs)
execute("echo 'import os' > src/utils.py", fs)

# Pipelines work
output = execute("grep -r 'def' src | wc -l", fs)
print(output)  # 1

# jq works
execute('echo \'{"name": "alice", "score": 42}\' > data.json', fs)
output = execute('jq -r ".name" data.json', fs)
print(output)  # alice

FileSystem protocol

Any object implementing these 16 methods works with termish -- no inheritance required:

class FileSystem(Protocol):
    def getcwd(self) -> str: ...
    def chdir(self, path: str) -> None: ...
    def read(self, path: str) -> bytes: ...
    def write(self, path: str, content: bytes, mode: str = "w") -> None: ...
    def exists(self, path: str) -> bool: ...
    def isfile(self, path: str) -> bool: ...
    def isdir(self, path: str) -> bool: ...
    def stat(self, path: str) -> FileMetadata: ...
    def mkdir(self, path: str, parents: bool = False, exist_ok: bool = False) -> None: ...
    def makedirs(self, path: str, exist_ok: bool = True) -> None: ...
    def remove(self, path: str) -> None: ...
    def rmdir(self, path: str) -> None: ...
    def rename(self, src: str, dst: str) -> None: ...
    def list(self, path: str = ".", recursive: bool = False) -> list[str]: ...
    def list_detailed(self, path: str = ".", recursive: bool = False) -> list[FileInfo]: ...
    def glob(self, pattern: str) -> list[str]: ...

Compatible filesystems

monkeyfs VirtualFS and IsolatedFS both satisfy the termish FileSystem protocol and can be passed directly to execute().

Builtin commands

Category Commands
Filesystem pwd, cd, mkdir, ls, touch, cp, mv, rm, basename, dirname
I/O echo, cat, head, tail, tee
Search grep, find
Text wc, sort, uniq, cut, sed, tr
Diff diff
Archive tar, gzip, gunzip, zip, unzip
Meta xargs
JSON jq

Development

uv sync --extra dev
uv run pytest

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

termish-0.1.0.tar.gz (59.9 kB view details)

Uploaded Source

Built Distribution

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

termish-0.1.0-py3-none-any.whl (50.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: termish-0.1.0.tar.gz
  • Upload date:
  • Size: 59.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for termish-0.1.0.tar.gz
Algorithm Hash digest
SHA256 23b86cc8d060bee54f99568ed46279d0bcceb3ee7b47d550ab059387efbf44c5
MD5 3259dbc7bd8132ef308c7918b06457de
BLAKE2b-256 3a149332c7b05a4f5c0ce0c7c98f2d26b29fb3c848e058267601cb149fd0be73

See more details on using hashes here.

File details

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

File metadata

  • Download URL: termish-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 50.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for termish-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9ad6e6f5a38bef7758778b87ab18eece97fe5681f8754259fdb7704d52b35329
MD5 9da722267af6e00db97d964a5c50cb48
BLAKE2b-256 00ebdc5e724bdf5e3cc428052fbb487f299b56a7b356e5e764e099564c62f991

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page