Linux – Bash reads and parses each line from a file

Bash reads and parses each line from a file… here is a solution to the problem.

Bash reads and parses each line from a file

I need to manage updates for specific software on multiple customers’ Linux servers. Provides updates by sending .tar.gz files to each server and augmenting them to overwrite old software files.

I’ve put the list of servers for my customers in a txt file like this:

user1@customer-server-1-address:22:/path/to/software/server1:NULL:Customer1name

user2@customer-server-2-address:2222:/path/to/software/server2:/etc/vpnc/client1.conf:Customer2name

user3@customer-server-3-address:22:/path/to/software/server3:NULL:Customer3name

The character “:” as a field delimiter; Field 1 is the server address, 2 is the port, 3 is the software path, 4 is used to determine whether to enable VPN tunneling first, and 5 is the customer name.

I have successfully created the following script:

#!/bin/bash

[...]

while IFS=':' read -ra array; do
    if [ "${array[3]}" != "NULL" ]; then
        echo
        echo "### USING VPN CONF '${array[3]}' FOR SERVER '${array[0]}'...###"
        sleep 1
        #vpnc ${array[3]}
        TUNNEL1=$(ifconfig | grep -o eth0)
        TUNNEL2='eth0'

if [ "$TUNNEL1" = "$TUNNEL2" ]; then
          echo "### TUNNEL IS UP ###"

scp -P${array[1]} $FILENAME.gz ${array[0]}:${array[2]}
          scp -P${array[1]} $FILELIST ${array[0]}:${array[2]}

ssh -p${array[1]} ${array[0]} 'cd '${array[2]}' && cat '${array[2]}'/'$FILELIST' | cpio --quiet -H ustar -o -0 -L -F '${array[2]}'/'$BACKUP_FILENAME
          ssh -p${array[1]} ${array[0]} 'gzip '${array[2]}'/'$BACKUP_FILENAME

ssh -p${array[1]} ${array[0]} 'tar -C '${array[2]}' -xf '${array[2]}'/'$FILENAME.gz
          ssh -p${array[1]} ${array[0]} 'cd '${array[2]}' && mkdir -p '$REMOTE_BACKUP_DIRECTORY' && rm -f '$FILELIST' && mv -f '$BACKUP_FILENAME.gz $REMOTE_BACKUP_ DIRECTORY

echo "### SERVER '${array[0]}' UPDATED ###"
          #vpnc-disconnect
          sleep 1
        else
          echo "### VPN ERROR IN SERVER '${array[4]}' ###"
        fi
    else
        echo

scp -P${array[1]} $FILENAME.gz ${array[0]}:${array[2]}
        scp -P${array[1]} $FILELIST ${array[0]}:${array[2]}

ssh -p${array[1]} ${array[0]} 'cd '${array[2]}' && cat '${array[2]}'/'$FILELIST' | cpio --quiet -H ustar -o -0 -L -F '${array[2]}'/'$BACKUP_FILENAME-${array[4]}
        ssh -p${array[1]} ${array[0]} 'gzip '${array[2]}'/'$BACKUP_FILENAME-${array[4]}

ssh -p${array[1]} ${array[0]} 'tar -C '${array[2]}' -xf '${array[2]}'/'$FILENAME.gz

ssh -p${array[1]} ${array[0]} 'cd '${array[2]}' && mkdir -p '$REMOTE_BACKUP_DIRECTORY' && rm -f '$FILELIST' && mv -f '$BACKUP_FILENAME-${array[4]}.gz $REMOTE_ BACKUP_DIRECTORY

echo "### SERVER '${array[4]}' UPDATED ###"
        echo
    fi;
done < "$CUSTOMER_SERVERS_FILE"

$CUSTOMER_SERVERS_FILE is the container file described earlier, and $FILENAME.gz is the update package.
$FILELIST is the list of files to update. Other variables set for other purposes.

The problem is, the whole thing only works efficiently for the first customer in my $CUSTOMER_SERVERS_FILE. The line above the first line was skipped, I don’t know why. Any tips? Thank you.

EDIT: As an answer to the duplicate objection, since the script is quite large, I didn’t think of any connection between the while and ssh em> object. I’d rather think about more grammatical errors. However, I can still remove the issue if needed.

Related Problems and Solutions