Use scp to copy a file to different servers

I have to copy a file to different servers almost every day. What I usually do is:

scp filename user@destinationhost:/destination/folder

I run this same command changing the destination host over and over again until I finish all the servers. What is the best (and fastest) way to transfer the same file to those different servers?

Another drawback is that I need to enter the password over and over again, but using rsa is not an option since several people can connect to the source server.

Edit - I found loop in commandlinefu that may do the trick:

 for h in host1 host2 host3 host4 ; { scp file user@$h:/destination_path/ ; }

There are various tools which can scp files to multiple hosts (with simultaneous connections), like pssh and kanif. In terms of passwords I would suggest using agent forwarding. This allows you to keep the key on your local machine, but use it when initiating SSH connections from another host. Otherwise, the --askpass option to the parallel-scp command from pssh makes it prompt for a password to use for every host.

If you can't install a tool to do this, setup agent forwarding (by adding the -A option to ssh when connecting to the machine you're doing this on) and then run scp in a loop like so:

for HOST in server1 server2 server3; do
    scp somefile $HOST:~/somedir/
done

Try doing this with an expect script e.g.

#!/bin/bash

HOSTS="h1.lan h2.lan h3.lan"

read -p "Password: " PASSWORD


for HOST in $HOSTS
do
    expect -c "
    spawn /usr/bin/scp file user@$HOST:/destination_path/
    expect {
    "*password:*" { send $PASSWORD\r;interact }
    }
    exit
    "
done

The above should be fairly straight forward to adapt to your requirements.


I think sshpass should be mentioned here. This is my go on sending a file to multiple targets, with a required password:

filePath="/home/download/textToSend.txt"
ip_range=("10.10.10.1" "10.10.10.2" "10.10.10.3" "10.10.10.4")
# Start file transfer
echo "Starting file transfer to ${#ip_range[@]} units."
for ((i=0; i<${#ip_range[@]}; ++i )) ;
do
   echo "Transfering ${filePath} to ${ip_range[$i]}..."
   sshpass -p password scp -o 'StrictHostKeyChecking=no' "${filePath}" root@${ip_range[$i]}:/home/downloads&
done
wait
echo "File transfers ended"