When managing multiple servers (501 in your case), executing the same script across all machines becomes essential. The standard SSH command execution works well for simple commands, but complete script execution requires a different approach.
The simplest method is to pipe your local script through SSH:
cat local_script.sh | ssh user@serverB 'bash -s'
For Perl scripts:
cat script.pl | ssh user@serverB 'perl'
This method provides better readability:
ssh user@serverB << 'EOF'
#!/bin/bash
# Your script content here
echo "Running on remote server"
EOF
For complex scripts, transferring first might be better:
scp script.sh user@serverB:/tmp/
ssh user@serverB "chmod +x /tmp/script.sh && /tmp/script.sh"
For your 500+ servers, use a loop with server list:
while read server; do
cat script.sh | ssh "$server" 'bash -s'
done < server_list.txt
For production environments, consider:
- Using SSH ControlMaster for faster connections
- Implementing error handling and logging
- Adding timeout parameters
for server in $(cat server_list.txt); do
echo "Processing $server"
if ! cat deploy.sh | ssh -o ConnectTimeout=10 "$server" 'bash -s'; then
echo "Failed on $server" >> errors.log
fi
done
When managing hundreds of servers, manually running scripts on each machine becomes impractical. The key requirement is executing local scripts stored on Server A across Server B and 500+ other servers via SSH without manual file transfers.
Basic SSH command execution works like this:
ssh user@serverB "ls -l /tmp"
But for multi-line scripts, we need better approaches.
The most straightforward solution using bash's here-document:
ssh user@serverB <<'ENDSSH'
#!/bin/bash
# Your entire script here
echo "Running on $(hostname)"
ENDSSH
For Perl scripts (assuming script.pl is local):
ssh user@serverB "perl -e \"$(cat script.pl | sed 's/\"/\\\"/g')\""
A more robust method that handles complex scripts:
# On Server A
encoded_script=$(base64 -w0 local_script.sh)
ssh user@serverB "echo $encoded_script | base64 -d | bash"
Use parallel execution with a server list file:
#!/bin/bash
while read server; do
ssh -n user@"$server" <<'ENDSSH'
# Script contents
echo "Running on $server"
ENDSSH &
done < server_list.txt
wait
Essential for production environments:
ssh user@serverB <<'ENDSSH' 2>> remote_errors.log
{
# Script contents
command1 || echo "Command failed on $(hostname)" >&2
} >> remote_output.log
ENDSSH
For faster execution across many servers:
# In ~/.ssh/config
Host *
ControlMaster auto
ControlPath ~/.ssh/%r@%h:%p
ControlPersist 5m