# ShellSh
A Python library for managing persistent shell sessions programmatically with non-blocking I/O.
## Features
- **Non-blocking command execution** - Commands return immediately without waiting for completion
- **Command status tracking** - Check if commands are still running with `is_alive()`
- **Flexible waiting** - Wait for command completion with optional timeouts using `wait()`
- **Persistent shell sessions** - Maintain environment variables, working directory, and state between commands
- **Real-time output streaming** - Capture output from long-running processes incrementally
- **Interactive program support** - Works with curses-based programs like `top`, `vim`, etc.
- **Process control** - Stop running commands with Ctrl+C programmatically
## Installation
```bash
pip install shellsh
```
## Quick Start
```python
from shellsh import ShellSh
import time
# Create a shell session
sh = ShellSh("my_session")
# Non-blocking mode (default)
sh.typeenter("ls -la")
time.sleep(0.5)
print(sh.flush()) # Get the output
# Wait for command completion
sh.typeenter("echo 'Processing...'; sleep 2; echo 'Done'")
sh.wait() # Blocks until command finishes
print(sh.flush())
# Check if command is running
sh.typeenter("sleep 5")
print(sh.is_alive()) # True - command is running
sh.wait(2) # Wait 2 seconds
print(sh.is_alive()) # True - still running after timeout
sh.stop() # Stop the command
# Blocking mode - waits for command completion
sh.setblocking(True)
sh.typeenter("sleep 2; echo 'Done'") # This will block for ~2 seconds
print(sh.flush()) # Output is ready immediately after typeenter returns
# Back to non-blocking
sh.setblocking(False)
sh.typeenter("echo 'Non-blocking'")
time.sleep(0.1)
print(sh.flush())
# Environment persists between commands
sh.typeenter("cd /tmp")
sh.typeenter("pwd")
sh.wait()
print(sh.flush()) # Prints: /tmp
# Stop long-running commands
sh.typeenter("sleep 100")
time.sleep(1)
sh.stop() # Sends Ctrl+C
# Clean up
sh.close()
```
## API Reference
### `ShellSh(name)`
Create a new shell session with the given name.
### `typeenter(line)`
Send a command to the shell. By default, returns immediately without waiting for execution. If `setblocking(True)` was called, blocks until the command completes.
### `flush()`
Retrieve new output since the last flush. Returns only unread output.
### `wait(seconds=None)`
Block until the current command completes or timeout is reached.
- `seconds=None`: Wait indefinitely until command completes (default)
- `seconds=float`: Maximum time to wait in seconds before returning
- Note: Timeout does not kill the command, it just stops waiting
### `is_alive()`
Check if a command is currently running.
- Returns `True` if a command is still executing
- Returns `False` if the last command has completed or no command was run
### `setblocking(blocking)`
Set blocking mode for `typeenter()`.
- `blocking=True`: `typeenter()` waits for command completion before returning
- `blocking=False`: `typeenter()` returns immediately (default)
### `stop()`
Send Ctrl+C to stop the currently running command.
### `close()`
Terminate the shell session and clean up resources.
## Context Manager
ShellSh supports context manager protocol:
```python
with ShellSh("session") as sh:
sh.typeenter("echo Hello")
time.sleep(0.5)
print(sh.flush())
# Automatically closed
```
## Use Cases
- Automating shell interactions
- Building terminal-based tools
- Testing command-line applications
- Managing long-running processes
- Creating interactive shell wrappers
## Requirements
- Python 3.7+
- Unix-like operating system (Linux, macOS)
## License
MIT
Raw data
{
"_id": null,
"home_page": "https://github.com/yourusername/shellsh",
"name": "shellsh",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "shell, subprocess, terminal, pty, automation",
"author": "Saturnino Adrales",
"author_email": "Saturnino Adrales <your.email@example.com>",
"download_url": "https://files.pythonhosted.org/packages/83/87/687a14f62df1d889104ccef8710ce23218aecb66963b1845d48a6711aaa8/shellsh-0.4.0.tar.gz",
"platform": null,
"description": "# ShellSh\n\nA Python library for managing persistent shell sessions programmatically with non-blocking I/O.\n\n## Features\n\n- **Non-blocking command execution** - Commands return immediately without waiting for completion\n- **Command status tracking** - Check if commands are still running with `is_alive()`\n- **Flexible waiting** - Wait for command completion with optional timeouts using `wait()`\n- **Persistent shell sessions** - Maintain environment variables, working directory, and state between commands\n- **Real-time output streaming** - Capture output from long-running processes incrementally\n- **Interactive program support** - Works with curses-based programs like `top`, `vim`, etc.\n- **Process control** - Stop running commands with Ctrl+C programmatically\n\n## Installation\n\n```bash\npip install shellsh\n```\n\n## Quick Start\n\n```python\nfrom shellsh import ShellSh\nimport time\n\n# Create a shell session\nsh = ShellSh(\"my_session\")\n\n# Non-blocking mode (default)\nsh.typeenter(\"ls -la\")\ntime.sleep(0.5)\nprint(sh.flush()) # Get the output\n\n# Wait for command completion\nsh.typeenter(\"echo 'Processing...'; sleep 2; echo 'Done'\")\nsh.wait() # Blocks until command finishes\nprint(sh.flush())\n\n# Check if command is running\nsh.typeenter(\"sleep 5\")\nprint(sh.is_alive()) # True - command is running\nsh.wait(2) # Wait 2 seconds\nprint(sh.is_alive()) # True - still running after timeout\nsh.stop() # Stop the command\n\n# Blocking mode - waits for command completion\nsh.setblocking(True)\nsh.typeenter(\"sleep 2; echo 'Done'\") # This will block for ~2 seconds\nprint(sh.flush()) # Output is ready immediately after typeenter returns\n\n# Back to non-blocking\nsh.setblocking(False)\nsh.typeenter(\"echo 'Non-blocking'\")\ntime.sleep(0.1)\nprint(sh.flush())\n\n# Environment persists between commands\nsh.typeenter(\"cd /tmp\")\nsh.typeenter(\"pwd\")\nsh.wait()\nprint(sh.flush()) # Prints: /tmp\n\n# Stop long-running commands\nsh.typeenter(\"sleep 100\")\ntime.sleep(1)\nsh.stop() # Sends Ctrl+C\n\n# Clean up\nsh.close()\n```\n\n## API Reference\n\n### `ShellSh(name)`\nCreate a new shell session with the given name.\n\n### `typeenter(line)`\nSend a command to the shell. By default, returns immediately without waiting for execution. If `setblocking(True)` was called, blocks until the command completes.\n\n### `flush()`\nRetrieve new output since the last flush. Returns only unread output.\n\n### `wait(seconds=None)`\nBlock until the current command completes or timeout is reached.\n- `seconds=None`: Wait indefinitely until command completes (default)\n- `seconds=float`: Maximum time to wait in seconds before returning\n- Note: Timeout does not kill the command, it just stops waiting\n\n### `is_alive()`\nCheck if a command is currently running.\n- Returns `True` if a command is still executing\n- Returns `False` if the last command has completed or no command was run\n\n### `setblocking(blocking)`\nSet blocking mode for `typeenter()`.\n- `blocking=True`: `typeenter()` waits for command completion before returning\n- `blocking=False`: `typeenter()` returns immediately (default)\n\n### `stop()`\nSend Ctrl+C to stop the currently running command.\n\n### `close()`\nTerminate the shell session and clean up resources.\n\n## Context Manager\n\nShellSh supports context manager protocol:\n\n```python\nwith ShellSh(\"session\") as sh:\n sh.typeenter(\"echo Hello\")\n time.sleep(0.5)\n print(sh.flush())\n# Automatically closed\n```\n\n## Use Cases\n\n- Automating shell interactions\n- Building terminal-based tools\n- Testing command-line applications\n- Managing long-running processes\n- Creating interactive shell wrappers\n\n## Requirements\n\n- Python 3.7+\n- Unix-like operating system (Linux, macOS)\n\n## License\n\nMIT\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A Python library for managing persistent shell sessions programmatically",
"version": "0.4.0",
"project_urls": {
"Homepage": "https://github.com/yourusername/shellsh",
"Issues": "https://github.com/yourusername/shellsh/issues",
"Repository": "https://github.com/yourusername/shellsh"
},
"split_keywords": [
"shell",
" subprocess",
" terminal",
" pty",
" automation"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "aaf02ce3bb58759c67d2882226ebae2c67edfe940a50728d32161c3dc548fdd0",
"md5": "1d552c54731925b87f81fbc4f960d7a2",
"sha256": "39e831af78b9c1f95bf2303e5486d9785a19f21ebc0f9f0370acb243f47c45cc"
},
"downloads": -1,
"filename": "shellsh-0.4.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "1d552c54731925b87f81fbc4f960d7a2",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 6828,
"upload_time": "2025-09-14T08:37:15",
"upload_time_iso_8601": "2025-09-14T08:37:15.394686Z",
"url": "https://files.pythonhosted.org/packages/aa/f0/2ce3bb58759c67d2882226ebae2c67edfe940a50728d32161c3dc548fdd0/shellsh-0.4.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "8387687a14f62df1d889104ccef8710ce23218aecb66963b1845d48a6711aaa8",
"md5": "72d9d68f356f3dcbdd1d3031935c95e3",
"sha256": "82a5f915c5600325f1dd76eafd4a086f3648d98aa8b36b6cf67020ae19fa74a9"
},
"downloads": -1,
"filename": "shellsh-0.4.0.tar.gz",
"has_sig": false,
"md5_digest": "72d9d68f356f3dcbdd1d3031935c95e3",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 6884,
"upload_time": "2025-09-14T08:37:17",
"upload_time_iso_8601": "2025-09-14T08:37:17.214456Z",
"url": "https://files.pythonhosted.org/packages/83/87/687a14f62df1d889104ccef8710ce23218aecb66963b1845d48a6711aaa8/shellsh-0.4.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-14 08:37:17",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "yourusername",
"github_project": "shellsh",
"github_not_found": true,
"lcname": "shellsh"
}