As a sysadmin or DevOps engineer working on macOS, you'll frequently need to execute identical commands across multiple servers. While you could manually SSH into each machine, this approach becomes impractical when managing dozens or hundreds of servers.
macOS offers several powerful tools for parallel SSH execution:
# Install pssh via Homebrew
brew install pssh
# Basic parallel SSH command
parallel-ssh -i -H "server1.example.com server2.example.com" -l username "uptime"
For interactive multi-server management:
brew install clusterssh
cssh server1 server2 server3
For more complex operations, consider Ansible:
# Install Ansible
brew install ansible
# Create inventory file
echo "[webservers]
server1.example.com
server2.example.com" > inventory.ini
# Run command on all servers
ansible webservers -i inventory.ini -a "df -h"
First, configure your SSH config file (~/.ssh/config):
Host *.example.com
User adminuser
IdentityFile ~/.ssh/id_rsa
StrictHostKeyChecking no
For simple cases, a bash script works well:
#!/bin/bash
servers=("server1" "server2" "server3")
command="sudo apt update && sudo apt upgrade -y"
for server in "${servers[@]}"
do
ssh "$server" "$command" &
done
wait
When executing parallel SSH commands:
- Use SSH keys instead of passwords
- Limit sudo privileges
- Consider using a jump host for sensitive environments
Managing multiple Linux servers simultaneously is a common requirement for DevOps engineers and system administrators. When you need to deploy configuration changes, run maintenance scripts, or gather system information across your server fleet, executing commands manually on each machine becomes impractical.
While macOS includes the built-in ssh
command, executing the same command across multiple servers requires either:
- Manual connection to each server
- Writing complex shell scripts with loops
- Maintaining server lists in separate files
1. pssh (Parallel SSH)
The most robust solution is to install pssh
(Parallel SSH) via Homebrew:
brew install pssh
Basic usage example:
pssh -h servers.txt -l username -A -i "uptime"
2. ClusterSSH
For interactive parallel sessions:
brew install clusterssh
cssh server1 server2 server3
3. Ansible Ad-Hoc Commands
For more advanced orchestration:
ansible all -i inventory.ini -m shell -a "df -h"
Example 1: Batch Updates
pssh -h production_servers.list -l deploy -i "sudo apt update && sudo apt upgrade -y"
Example 2: Status Checking
pssh -h webservers.txt -l admin -P "systemctl status nginx"
Example 3: File Distribution
pscp -h servers.txt -l user config.json /etc/app/config.json
For regular maintenance tasks, consider creating a shell script:
#!/bin/bash
SERVERS=("web1.example.com" "web2.example.com" "db1.example.com")
for server in "${SERVERS[@]}"; do
ssh admin@$server "$1"
done
Always use SSH keys instead of passwords. Generate keys with:
ssh-keygen -t ed25519
ssh-copy-id user@server
For sensitive operations, implement proper sudo configurations and consider using SSH certificates instead of raw keys.