Skip to main content

ssherd

Run commands on many servers at once — one Python file, zero dependencies, powered by your OpenSSH client.

CI License: MIT Python

English | 简体中文

ssherd is a small batch-SSH CLI for server fleets. Your ~/.ssh/config (or a project-local .ssh/config) is the inventory: ssherd reads the Host aliases, fans out commands in parallel, and lets the real ssh client handle everything it already does best — addresses, jump hosts (ProxyJump), users, keys, host keys.

Works on Linux, macOS, and Windows (Git-Bash / PowerShell).

ssherd running whoami on 16 servers at once, grouping identical output into one block

Features

  • Single file, zero dependencies — copy ssherd.py anywhere, needs only Python 3.9+ and ssh
  • SSH config as inventory — selectors by name, comma list, or range (web-01..web-16, all)
  • Parallel execution with a live per-device progress bar
  • Smart grouped output — identical results collapse into one block, outliers shown as compact diffs (--diff)
  • Jump hosts / keys / users — all resolved natively by OpenSSH, never re-implemented
  • Password auth support via OpenSSH's official SSH_ASKPASS_REQUIRE=force (no sshpass, never touches your tty)
  • Sudo fan-outsudo -S wrapping with one local password prompt
  • add-user — generates plain, auditable bash commands by default (--exec to run them)

Installation

pipx install ssherd    # isolated venv + global command (recommended)
pip install ssherd     # or plain pip — works on any OS

Requirements: Python 3.9+ and the OpenSSH client (ssh) you already have.

Prefer no installer at all? It's one self-contained file — grab it, read it, hack it:

curl -fsSL https://raw.githubusercontent.com/trdthg/ssherd/master/ssherd.py \
  -o ~/.local/bin/ssherd && chmod +x ~/.local/bin/ssherd

Uninstall: pipx uninstall ssherd or pip uninstall ssherd.

Quick start

# the inventory is just your ssh config Host aliases
python -m ssherd list

# run in parallel across a range
python -m ssherd run web-01..web-16 -- whoami

# comma lists and single hosts work too
python -m ssherd run web-01,web-05,db-01 -- hostname

# sudo: prompts once, wraps remotely with sudo -S
python -m ssherd run --sudo db-01..db-32 -- apt update

# scriptable: pass passwords inline (note: lands in shell history)
python -m ssherd run --sudo=SUDOPASS db-01 -- systemctl restart nginx

# group identical outputs, show only the differences
python -m ssherd run all --diff -- 'cat /etc/os-release'

Inventory

Devices are the Host entries in your SSH config (Host * wildcards are skipped):

Host web-01
    HostName 192.0.2.10
    User deploy
    # ProxyJump jumpbox   ← jump hosts just work, ssh handles them

A .ssh/config in the current directory takes precedence over ~/.ssh/config, so a fleet per project is one folder away. Put .ssh/ in .gitignore and real IPs never get committed. Selectors accept aliases, comma lists, ranges (web-01..web-16), and all / *.

Creating users

add-user prints the plain bash commands (useradd / usermod / chpasswd) for you to audit and paste, or to wrap in your own loop. Add --exec to fan them out through the same parallel channel:

python -m ssherd add-user web-01..web-16 deploy
python -m ssherd add-user web-01..web-16 deploy --sudo --password 'TempPass-123' --exec

Why not Ansible / pssh / fabric?

They are great; this is for the other 90% of ops work: one-off fleet commands where you refuse to install anything, write a playbook, or learn a DSL. ssherd delegates all connection semantics to OpenSSH, so anything your ssh can reach, ssherd can reach — including bastion hosts.

Tests

python -m unittest discover -v

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

ssherd-0.1.2.tar.gz (12.7 kB view details)

Uploaded Source

Built Distribution

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

ssherd-0.1.2-py3-none-any.whl (12.9 kB view details)

Uploaded Python 3

File details

Details for the file ssherd-0.1.2.tar.gz.

File metadata

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

File hashes

Hashes for ssherd-0.1.2.tar.gz
Algorithm Hash digest
SHA256 0239580a5230fd0551fba8bd8faacbd800f2b9e08b5fb462cfd80bf9b7da237f
MD5 01baac3d316d3a5d632cf499c5dd3e4c
BLAKE2b-256 283c539707261d7102797139aaf1ec0f44cb6bb0e1bee166139db2297d44e4e6

See more details on using hashes here.

Provenance

The following attestation bundles were made for ssherd-0.1.2.tar.gz:

Publisher: publish.yml on trdthg/ssherd

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

File details

Details for the file ssherd-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: ssherd-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 12.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ssherd-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e14b4af1740e16638b166580e850404affdbf5082ff60024cdd6ac7a971d230a
MD5 5da5316f498a56f496ebde7f7f4df1b2
BLAKE2b-256 0317b307e6f817b91ebdd7da8fcae20757d47b983683cddb72452220b6da8513

See more details on using hashes here.

Provenance

The following attestation bundles were made for ssherd-0.1.2-py3-none-any.whl:

Publisher: publish.yml on trdthg/ssherd

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

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 files

0.1.1

2 files

0.1.0

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