Skip to main content

sdev

Small toolkit for automating a serial-attached Linux shell.

Installation

pip install -e .

CLI

# Run a command
sdev -p "ls /proc/meminfo" -d /dev/ttyUSB0 -b 115200

# Stream output incrementally
sdev -p "tail -f /var/log/syslog" --stream

# Stream with server-side regex filter
sdev -p "tail -f /var/log/syslog" --stream --grep "ERROR"

# Stream with complete-line output only
sdev -p "dmesg" --stream --line-mode

# Parse output with regex
sdev -p "cat /proc/meminfo" --parse "Mem.*"

# Wait for a specific output marker instead of shell prompt
sdev -p "./mnn_perf -m model.mnn" --end-flag "Frame rate:"

# Clear stray processes before running a command
sdev -p "uptime" --doctor

# Save defaults so you can omit -d and -b
sdev set-default /dev/ttyUSB0 115200
sdev -p "ls /proc/meminfo"

# Send Ctrl+C to interrupt a running command (without -p)
sdev --interrupt -d /dev/ttyUSB0 -b 115200

# Detect serial boards on this system
sdev --probe
sdev --probe --probe-baud 9600 --probe-baud 38400

# Custom prompt patterns for non-standard shells
sdev -p "ls" --prompt "[root@board]# " --prompt "admin@box> "

CLI options

Flag Description
-p, --command Command to execute
-d, --device Serial device path
-b, --baud Baud rate
-t, --timeout Timeout in seconds (default: 300)
--stream Incremental output instead of buffered
--grep REGEX Filter --stream lines by regex
--line-mode Only yield complete lines in --stream
--parse REGEX Show only matching lines
--end-flag STR Stop when this string appears in output
--doctor Clear foreground processes before command
--prompt PATTERN Custom shell prompt pattern (repeatable)
--interrupt Send Ctrl+C and wait for prompt
--probe Detect serial boards and print info
--probe-baud BAUD Baud rates to try during --probe (repeatable)
set-default Persist device/baud as defaults

Design Goals

  • Stability: strict 5-minute timeout on all blocking operations
  • Simplicity: small surface area, obvious API
  • Predictability: prompt detection to determine command completion
  • Streaming: incremental output for long-running commands
  • Parsing: structured output with optional regex filtering

Python API

import sdev

# Session-based (recommended)
with sdev.SerialSession("/dev/ttyUSB0", 115200) as session:
    result = session.cli("ls /proc/meminfo")
    print(result.output)

# Custom prompt detection for non-standard shells
session = sdev.SerialSession("/dev/ttyUSB0", 115200, prompts=[b"[root@board]# "])
session.connect()

# Streaming for long-running commands
for chunk in session.stream("tail -f /var/log/syslog"):
    print(chunk, end="")

# Streaming with line mode — only yields complete lines
for line in session.stream("tail -f /var/log/syslog", line_mode=True):
    process(line)

# Streaming with server-side filter
for chunk in session.stream("tail -f /var/log/syslog", filter_fn=lambda t: t.upper()):
    print(chunk, end="")

# Parsing with regex filtering
parsed = session.parse("cat /proc/meminfo", pattern=r"Mem.*")
print(parsed.matched)

# Wait for a specific output marker instead of shell prompt
# Useful for benchmarks that print results then keep running
result = session.cli("./mnn_perf -m model.mnn", end_flag="Frame rate:")

# Interrupt a running command (sends Ctrl+C and waits for prompt)
session.interrupt(timeout=5)

# Clear stray foreground processes and get a clean prompt
session.doctor()

# Wait until no data arrives for N seconds (boot completion)
session.wait_for_silence(timeout=1.5)

# Recover from device reboot without creating a new session
session.reconnect()

# Monitor CPU/memory during long operations
usage = sdev.resource_usage()
print(f"RSS: {usage['memory_mb']} MB, CPU: {usage['cpu_percent']}%")

# Detect serial boards and get OS/arch info
for device in sdev.probe():
    print(f"{device['device']} @ {device['baud']}: {device['info']['os_name']}")

# Send raw bytes over serial (control sequences, custom protocols)
sdev.connect("/dev/ttyUSB0", 115200)
n = sdev.write(b"reboot\n")
print(f"Wrote {n} bytes")

# Clear stray foreground processes on the default connection
sdev.doctor()

# Wait for boot completion (no serial data for N seconds)
sdev.wait_for_silence(timeout=2.0)

Thread safety

Each SerialSession has an internal threading.Lock. Only one cli() or stream() call can run at a time per session. Concurrent callers will raise RuntimeError after 10s if the lock is held. interrupt() does not acquire the lock — it remains the emergency escape hatch.

Module-level convenience API

sdev.connect("/dev/ttyUSB0", 115200)
result = sdev.cli("ls /proc/meminfo")
sdev.disconnect()

License

MIT

Metadata

Release files for sdev 1.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sdev 1.0.3
File Size Uploaded
sdev-1.0.3.tar.gz 41.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sdev 1.0.3
File Interpreter ABI Platform
sdev-1.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 58.8 kB

Release files / sdev-1.0.3.tar.gz

Download URL sdev-1.0.3.tar.gz
Size 41.4 kB
Tags Source
SHA-256 checksum
How to use checksums
e9dc9d2ddd6dac222ee33a38b7098281a714844748414aaf0b628b0c6ca65a35
BLAKE2b-256 checksum
How to use checksums
d9efe6b0a8b41245d9b6222413dfbb1dba9a1a307348e55a9578eb32c582def4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.13

Release files / sdev-1.0.3-py3-none-any.whl

Download URL sdev-1.0.3-py3-none-any.whl
Size 17.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a24a2194535a2318783c9dc46459f31df127ae34ccb1c1c9a3b308087f9786ee
BLAKE2b-256 checksum
How to use checksums
e6048ce293f0973beeccf7f9f6f5ec99b54784d15410bcebb626bde0ebd33fa9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.13

Release history Release notifications | RSS feed

This release

1.0.3 This release

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release 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