1

I have a given shell script:

#!/bin/bash

USERNAME=xenobot
SSH_KEY_LOCATION="~/.ssh/id_rsa"
FILE="server.info"
while read -r server_ip  package_type; do  
    if [[ $package_type == "deb" ]]; then
         echo "For $server_ip package type is $package_type"
         DPKG_FILE_PATH=$(ls ./src/dpkg/dpkg-*)
             DPKG_FILE=$(basename $DPKG_FILE_PATH)
             echo "$DPKG_FILE located at $DPKG_FILE_PATH will be transfered via SSH to server"
         scp ./src/dpkg/${DPKG_FILE} $USERNAME@$server_ip:/tmp
             ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -l ${USERNAME} ${server_ip} "cd /tmp; sudo dpkg -i *.deb"
    elif [[ $package_type == "rpm" ]]; then
         echo "For $server_ip package type is $package_type"
             RPM_FILE_PATH=$(ls ./src/rpm/rpm-*)
             RPM_FILE=$(basename $RPM_FILE_PATH)
             echo "$RPM_FILE located at $RPM_FILE_PATH will be transfered via SSH to server"
         scp -o 'StrictHostKeyChecking no' ./src/rpm/${RPM_FILE} $USERNAME@$server_ip:/tmp
         echo "$RPM_FILE has been successfuly transfered to server!"
         ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -l ${USERNAME} ${server_ip} "cd /tmp; sudo rpm -ivh --force $RPM_FILE"
    fi
done <"$FILE"

And I have following file server.info, from which previous shell script reads:

213.136.80.123 rpm 213.136.91.102 rpm

The problem with it, as it is execute only once from first line, and just stops there without executing the second line

I have tried just to print output from this server.info using the same while read -r and it seems that outputs just fine like this

#!/bin/bash

USERNAME=xenobot
SSH_KEY_LOCATION="~/.ssh/id_rsa"
FILE="server.info"
while read -r server_ip  package_type; do  
    if [[ $package_type == "deb" ]]; then
         echo "For $server_ip package type is $package_type"
    elif [[ $package_type == "rpm" ]]; then
         echo "For $server_ip package type is $package_type"
    fi
done <"$FILE"

Output:

213.136.80.123 rpm 213.136.91.102 rpm

So it seems like it outputs two separate lines, however I do not know why it runs script only once in bigger example

4
  • No reason to use ls. Just rpm_file_path=(./src/rpm/rpm-*) to make rpm_file_path be an array. Commented Nov 21, 2022 at 21:40
  • The bug this question asks about is BashFAQ #89 Commented Nov 21, 2022 at 21:41
  • (btw, suggesting rpm_file_path instead of RPM_FILE_PATH is deliberate: all-caps names are used for variables meaningful to the OS and shell; lowercase names are reserved for application use; see pubs.opengroup.org/onlinepubs/9699919799/basedefs/…, keeping in mind that setting a regular shell variable overwrites any like-named environment variable) Commented Nov 21, 2022 at 21:44
  • Also, the quotes in SSH_KEY_LOCATION="~/.ssh/id_rsa" are wrong; putting the ~ inside the quotes stops it from being expanded. Use ssh_key_location=~/.ssh/id_rsa, or ssh_key_location=~/".ssh/id_rsa" -- but don't quote the tilde if you want it replaced with the path to your home directory. If you want something that can be used in quotes, use $HOME (all caps because it's meaningful to POSIX-defined tools!) instead of ~. Commented Nov 21, 2022 at 21:46

1 Answer 1

1

Try using a different file descriptor for your list other than 0, 1, or 2 (in this case it's set to 3).

while read -r server_ip package_type <&3; do
    ...
done 3<"$FILE"

If that works, then what's going on here is that ssh -- being an interactive program -- is sucking up your STDIN input.

Sign up to request clarification or add additional context in comments.

1 Comment

In How to Answer, note the section Answer Well-Asked Questions, and the bullet point therein about questions that "have been asked and answered many times before".

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.