Batch File Transfer and Command Execution with Shell Scripts

When managing a small number of machines, handling them one by one might be acceptable. However, when dealing with dozens or hundreds of machines, repeating the same commands manually becomes tedious and error-prone. A more efficient approach is to write batch processing shell scripts. This article documents several batch processing scripts, including batch file transfer via scp, batch command execution without interaction, and batch command execution with interaction using expect.

Prerequisites:

  • All target machines must be listed in a file named ip.txt, one IP address per line:
192.168.10.201
192.168.10.202
192.168.10.203
192.168.10.204
192.168.10.205
  • The management machine must be able to SSH into each target machine without a password.

1. Batch File Transfer (scp)

Create a script file and make it executable:

touch xscp.sh
chmod +x xscp.sh

Script content (xscp.sh):

#!/bin/bash
for line in `cat $1`
do
    if [ "$3" == "" ]
    then
        # Transfer entire directory
        echo scp -r $2/ $line:$2/
        scp -r $2/ $line:$2/
    else
        # Transfer specific files
        echo scp ${@:3} $line:$2/
        scp ${@:3} $line:$2/
    fi
done

Example 1: Transfer specific files

./xscp.sh ip.txt /opt/soft/ filename1 filename2 ...
  • $1 (ip.txt): File containing IP addresses, one per line.
  • $2 (/opt/soft/): Destination directory on target machines.
  • ${@:3}: List of files to transfer.

Example 2: Transfer entire directory

./xscp.sh ip.txt /opt/soft/

If no specific files are provided, the script recursively transfers all contents of the source directory (/opt/soft/) to the same path on each target machine.

2. Batch Command Execution (Non-interactive)

Create a script file and make it executable:

touch xcall.sh
chmod +x xcall.sh

Script content (xcall.sh):

#!/bin/bash
params=${@:2}
for line in `cat $1`
do
    echo  "=============  {print %s, $line} $params ============="
    ssh $line "$params"
done

Example 1:

./xcall.sh ip.txt hostname
  • $1: IP list file.
  • ${@:2}: Command to execute (can be a single command without quotes).

Example 2:

./xcall.sh ip.txt "rpm -qa | grep lzo"

For complex commands, its recommended to wrap them in double quotes to preserve structure.

3. Batch Command Execution (Interactive)

Some remote commands require user interaction, such as confirming installation prompts (yes/no) or entering passwords. Manual input for many machines is impractical. Using expect automates these interactions.

First, install expect on the management machine:

yum -y install expect

Key expect commands:

  • spawn: Starts a new process to execute a shell command.
  • expect: Waits for a specific string from the process.
  • send: Sends a string to the process.
  • interact: Returns control to the user after interaction completes.

Example 1: Interactive script for Java keytool command

Create the script:

touch xcall-keytool-list.sh
chmod +x xcall-keytool-list.sh

Script content (xcall-keytool-list.sh):

#!/bin/bash
params=${@:2}
for line in `cat $1`
do
    echo  "============ $line $params ============="
    /usr/bin/expect << EOF
   set time 20
   spawn  ssh $line "$params"
   expect {
        "*password:"
          { send "changeit\r" } 
   }
   expect eof
EOF
done

Execute to list certificates in Java keystore (password: changeit):

./xcall-keytool-list.sh ip.txt "/home/software/java/bin/keytool -list -keystore /home/software/java/jre/lib/security/cacerts | grep baidu"

Example 2: Generic interactive script

Create the script:

touch xcall-interaction.sh
chmod +x xcall-interaction.sh

Script content (xcall-interaction.sh):

#!/bin/bash
# IP file
iptxt=$1
# Command to execute
command=$2
# Prompt string to expect (e.g., "password:" or "yes/no:")
initem=$3
# Input to send (e.g., the password or "yes")
input=$4
echo "--- command:$command ---"
echo "--- 输入项:$initem ---"
echo "--- 输入内容:$input ---"
for line in `cat $iptxt`
do
   echo  "============ $line $command ============="
   if [ "$initem" = "" ]
   then
        ssh $line "$command"
   else
        /usr/bin/expect << EOF
        set time 20
        spawn  ssh $line "$command"
        expect {
            "*$initem:"
            { send "$input\r" } 
        }
        expect eof
EOF
    fi
done

Execute with parameters:

./xcall-interaction.sh ip.txt "/home/software/java/bin/keytool -list -keystore /home/software/java/jre/lib/security/cacerts | grep baidu" password changeit
  • $1: IP list file.
  • $2: Command to execute (should be quoted).
  • $3: The prompt string to match (e.g., password). If empty, the script runs the command non-interactively.
  • $4: The input to send when the prompt is matched.

Tags: Shell batch scp ssh expect

Posted on Sat, 09 May 2026 18:57:36 +0000 by jimmy patel