PyPSSH is a powerful and easy-to-use parallel SSH client designed for large-scale server management. It supports features such as batch command execution, parallel file transfer, connectivity testing, labeled host selection, and namespace isolation, helping operations engineers significantly improve work efficiency.
| Feature | Description |
|---|---|
| π Parallel Execution | Supports parallel command execution and file transfer across thousands of servers |
| π― Smart Selection | Flexibly select target hosts through IP expressions, label expressions, and server groups |
| π Namespaces | Configuration isolation for multiple environments (testing, staging, production) |
| π₯οΈ User-Friendly Interface | Colored progress bars, real-time output, failure details |
| π¦ Rich Output Formats | Supports JSON / YAML / templated / silent output |
| π§ Easy to Extend | Modular design, convenient for secondary development |
You can download pre-built binaries for CentOS 8 (mainly depends on a higher version of GLIBC) from the GitHub releases page.
You can also install pypssh by compiling:
$ git clone https://github.com/souloss/pypssh
$ cd pypssh
$ uv sync
$ ./script/build/package_exec # Build a single binary using pyinstaller
$ ./dist/pypssh --versionpypssh config add-server 192.168.1.10 \
--name web1 \
--username root \
--password 123456 \
--label env=prod,role=webpypssh exec --hosts "192.168.1.0/24" --sudo "systemctl restart nginx"pypssh file upload ./dist.tar.gz /opt/web/ \
--group web-servers \
--recursive \
--preservepypssh ping --selector "env=prod" --max-concurrent 100# Create a namespace
pypssh config create-namespace prod --description "Production Environment"
# List namespaces
pypssh config list-namespaces
# Delete a namespace
pypssh config delete-namespace test --force# Add
pypssh config add-server 10.0.0.21 --name db1 --username ubuntu --private-key-path ~/.ssh/id_rsa
# List
pypssh config list-servers --namespace prod
# Update
pypssh config update-server web1 --add-label region=us-east-1 --remove-label temp=true
# Delete
pypssh config delete-server web1 --force# Create
pypssh config add-group web-servers \
--description "All web nodes" \
--ip-expression "192.168.1.[10:50]" \
--label-expression "role=web" \
--default-username deploy
# Use
pypssh exec --group web-servers "uptime"| Option | Example | Description |
|---|---|---|
--hosts |
192.168.1.0/24,!192.168.1.100 |
IP expression |
--selector |
env=prod,role=web |
Label expression |
--group |
web-servers |
Server group |
--server |
web1 |
Single server |
--max-concurrent |
100 |
Concurrency level |
--timeout |
30 |
Command timeout |
--output |
json |
Output format |
--template |
"${host}: ${stdout}" |
Custom template |
pypssh exec \
--namespace prod \
--selector "env=prod,role=web,!maintenance" \
--sudo \
--output json \
--output-file results.json \
"apt update && apt upgrade -y"# Export one namespace
pypssh config export prod.yml --namespace prod
# Export all
pypssh config export all.yml
# Import
pypssh config import prod.yml --namespace prod | Example | Description |
|---|---|
192.168.1.10 |
Single IP |
192.168.1.0/24 |
CIDR |
192.168.1.10-192.168.1.20 |
Range |
192.168.1.10,192.168.1.15 |
List |
192.168.1.0/24 !192.168.1.100 |
Exclude |
192.168.[1:3].[10:20] |
Field range |
| Example | Description |
|---|---|
env=prod |
Equals |
role!=db |
Not equals |
env in (prod,staging) |
Inclusion |
region notin (cn-north-1) |
Exclusion |
has(sshd) |
Tag existence |
count(disk) > 2 |
Count comparison |
startswith(hostname, "web") |
Prefix match |
regex(hostname, "web-\d+") |
Regex match |
ssh-protocol - SSH.COM
tenacity document
click document
This project is licensed under the MIT License. See the LICENSE file for the full license text.