Skip to content

hansipie/Shelld

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Shelld

A persistent shell daemon written in C++. Shelld maintains shell sessions that persist across client connections, enabling command execution via API without spawning new shell processes for each command.

Features

  • Persistent sessions: Maintains context (environment variables, current directory) between commands
  • Multiple sessions: Several independent shells running in parallel
  • PTY support: Compatible with interactive programs (vim, less, htop, etc.)
  • Async job execution: Run long-duration commands without blocking (NEW ✨)
  • Pseudo-streaming: Poll job output for real-time progress updates (NEW ✨)
  • Signal handling: Send SIGINT to running processes
  • Configurable timeout: Execution time limit per command (10 min default)

Architecture

┌─────────────┐     ┌──────────────────┐     ┌─────────────┐
│   Client    │────▶│  Daemon (Shell)  │────▶│   PTY/Bash  │
│  (CLI/API)  │◀────│   - Queue cmds   │◀────│             │
└─────────────┘     │   - I/O Handling │     └─────────────┘
                    └──────────────────┘

Use Cases

  • Automation: Execute scripts/commands from other applications
  • CI/CD Integration: Entry point for automation pipelines
  • Remote execution: Execute commands remotely via API
  • IDE/Editors: Backend for integrated terminals

Installation

From source:

git clone https://github.com/hansipie/shelld.git
cd shelld/src

# With CMake
mkdir build && cd build
cmake ..
make

# Or direct compilation
g++ -std=c++17 -Wall -Wextra -Wpedantic -o shelld \
    main.cpp Daemon.cpp Session.cpp UnixSocket.cpp -pthread

Usage

Start the daemon

./shelld
# Listening on /tmp/shelld.sock

Commands

Synchronous Execution

# Show available commands
echo "HELP" | nc -U /tmp/shelld.sock

# Create a session
echo "CREATE mysession" | nc -U /tmp/shelld.sock

# List sessions
echo "LIST" | nc -U /tmp/shelld.sock

# Execute a command (blocks until done, 30s timeout)
echo "EXEC mysession ls -la" | nc -U /tmp/shelld.sock

# Destroy a session
echo "DESTROY mysession" | nc -U /tmp/shelld.sock

# Stop the daemon
echo "EXIT" | nc -U /tmp/shelld.sock

Asynchronous Execution (NEW ✨)

For long-running commands, use the async API:

# Start an async job (returns immediately with job ID)
echo "EXEC_ASYNC mysession 'npm run build'" | nc -U /tmp/shelld.sock
# Output: OK: Job 1

# Check job status
echo "JOB_STATUS mysession 1" | nc -U /tmp/shelld.sock
# Output: RUNNING elapsed_ms=5234

# Get partial output (while running)
echo "JOB_OUTPUT mysession 1 partial" | nc -U /tmp/shelld.sock

# Get final output (after completion)
echo "JOB_OUTPUT mysession 1" | nc -U /tmp/shelld.sock

# List all jobs
echo "JOB_LIST mysession" | nc -U /tmp/shelld.sock

# Cancel a running job
echo "JOB_CANCEL mysession 1" | nc -U /tmp/shelld.sock

# Cleanup finished job
echo "JOB_CLEANUP mysession 1" | nc -U /tmp/shelld.sock

Pseudo-streaming pattern:

# Use the helper script for automatic polling
./examples/stream_job.sh mysession "npm run build" 2

See examples/ for ready-to-use scripts!

Protocol

Simple text-based protocol over Unix socket:

Session Management

Command Description
CREATE <name> Create a new session
LIST List all active sessions
DESTROY <name> Destroy a session
HELP Show available commands
EXIT Stop the daemon

Synchronous Execution

Command Description
EXEC <name> <cmd> Execute command (blocks, 30s timeout)
INTERRUPT <name> Send SIGINT (Ctrl+C) to session
SETENV <name> <key> <value> Set environment variable

Asynchronous Execution (NEW ✨)

Command Description
EXEC_ASYNC <name> <cmd> Start async job, returns job ID
JOB_STATUS <name> <id> Get job status (RUNNING/COMPLETED/etc)
JOB_OUTPUT <name> <id> [partial] Get job output
JOB_LIST <name> List all jobs in session
JOB_CANCEL <name> <id> Cancel running job
JOB_CLEANUP <name> <id> Remove finished job

Job States: RUNNING, COMPLETED, TIMEOUT, CANCELLED, FAILED

📚 Full documentation: See docs/ASYNC_COMMANDS.md for complete guide with diagrams and examples.

Configuration

Option Description Default
Socket path Unix socket location /tmp/shelld.sock

Security

  • Unix socket: Filesystem permissions control access
  • Client UID verification: Planned feature

Similar Projects

Project Description
shpool Lightweight tmux alternative in Rust
shellmgr Multi-shell REST API in Go
tmux Terminal multiplexer

License

MIT

About

Shell Daemon

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors