SoFunction
Updated on 2025-03-09

Bulk SCP script tool written by shell combined with expect

When deploying a task, one of the necessary processes is to send some files, such as installation packages, to a large number of servers. Although Yu Ge's scripts are available: python scripts written through the ssh and scp functions provided by the paramiko module. But I am still afraid of python (although I have worked hard to learn in my free time), so I used a combination of shell and expect scripts to write this batch scp scripting tool.

expect is used to automatically execute command-line interactive tasks in the Linux environment, such as scp, ssh and other tasks that require users to manually enter passwords and then confirm. With this tool, you can define the situations you may encounter during the scp process, and then write the corresponding processing statements to automatically complete the scp operation.

If you need the expect tool, you can use apt-get or pacman package management tools in the Linux environment to get the installation, or go to the website of the expect open source project:/Come to get it.

After installing expect, you can try to complete the scp task on a single server using the following code:

#!/usr/bin/expect
set timeout 10
set host [lindex $argv 0]
set username [lindex $argv 1]
set password [lindex $argv 2]
set src_file [lindex $argv 3]
set dest_file [lindex $argv 4]
spawn scp $src_file $username@$host:$dest_file
 expect {
 "(yes/no)?"
  {
  send "yes\n"
  expect "*assword:" { send "$password\n"}
 }
 "*assword:"
{
 send "$password\n"
}
}
expect "100%"
expect eof


Note that the first line at the beginning of the code specifies the path to expect, the same as the shell script. This sentence specifies where to find the corresponding startup program when the program is executed. The code also sets the timeout time to 10 seconds at the beginning. If you encounter an exception not specified in the code when executing the scp task, the execution of the script will automatically terminate after waiting for 10 seconds.

From the first few lines of the above code, we can see that I have set 5 parameters that need to be entered manually for this script, namely: the IP, username, password of the target host, local file path, and file path in the target host. If you save the above script as an expect_scp file, you need to enter the command according to the following specifications when executing it in the shell:
./expect_scp 192.168.75.130 root 123456 /root/src_file /root/dest_file

After the above command is executed, the src_file file in the local /root directory will be copied to /root in host 192.168.75.130 with user name root and password 123456, and the source file will be renamed to dest_file.

spawn represents a statement executed on the local terminal. After the statement starts executing, expect starts to capture the output information of the terminal and then performs the corresponding operation. The captured (yes/no) content in the expect code is used to complete the operation of saving the key when accessing the target host for the first time. With this sentence, the scp task reduces the interruption. The expect eof at the end of the code corresponds to spawn, indicating the termination of the capture terminal output information.

With this expect code, you can only complete the scp task for a single remote host. If you need to implement batch scp tasks, you need to write another shell script to call this expect script.

Shell script:

Copy the codeThe code is as follows:

#!/bin/sh
list_file=$1
src_file=$2
dest_file=$3
cat $list_file | while read line
do
   host_ip=`echo $line | awk '{print $1}'`
   username=`echo $line | awk '{print $2}'`
   password=`echo $line | awk '{print $3}'`
   echo "$host_ip"
   ./expect_scp $host_ip $username $password $src_file $dest_file
done

3 parameters are specified: the location of the list file, the path of the local source file, and the path of the remote host target file. It should be noted that the list file in it specifies the remote host ip, username, and password. These information need to be written in the following format:
IP username password

The middle is separated by spaces or tab keys. The information of multiple hosts requires multiple lines of content to be written, such as:
192.168.75.130 root 123456
192.168.75.131 knktc testpass

This specifies the information of two remote hosts. Note that if there are special characters such as "$" and "#" in the remote host password, you need to add escape characters before these special characters when writing the list file, otherwise the wrong password will be entered during execution.

For this shell script, save it as a batch_scp.sh file, and put it in the same directory as the expected_scp file and list file (defined as a file) you just saved. When executing, just enter the command as follows:
./batch_scp.sh ./ /root/src_file /root/destfile
Using these two script files, you can simply complete the batch scp task.
In fact, the task of batch scp is not difficult, but the task of batch ssh may encounter trouble.