Bash while loop iterates only once whenever body contains ssh

I’m reading host information from a text file and pass it to an ssh command:
The text file contains the host, user and password for the ssh command

while read LINE
do
    R_USER=$(echo $LINE | cut -d ',' -f 1)                  
    R_HOST=$(echo $LINE | cut -d ',' -f 2)                                  
    PY_SCRIPT=$(echo $LINE | cut -d ',' -f 4)               

    ssh $R_USER@$R_HOST 'touch /home/user/file_name.txt'

done </path_name/file_name

As it turns out the while loop is only executed once even if the host text file contains multiple host information.
When I remove the ssh command the while loop gets executed as much as there are lines in the host information text file.

Read More

Not sure why this is so.
Any information on this?

Roland

Related posts

Leave a Reply

2 comments

  1. The default standard input handling of ssh drains the remaining line from the while loop.

    To avoid this problem, alter where the problematic command reads standard input from. If no standard input need be passed to the command, read standard input from the special /dev/null device:

    while read LINE
      do
        R_USER=$(echo $LINE | cut -d ',' -f 1)                  
        R_HOST=$(echo $LINE | cut -d ',' -f 2)                                  
        PY_SCRIPT=$(echo $LINE | cut -d ',' -f 4)               
    
        ssh $R_USER@$R_HOST 'touch /home/user/file_name.txt' < /dev/null
    
    done </path_name/file_name
    

    Or alternatively, try using ssh -n which will prevent ssh from reading from standard input. For instance:

    ssh -n $R_USER@$R_HOST 'touch /home/user/file_name.txt'
    
  2. If the file is white space separated

    host1 user password
    host2 user password
    

    then a simple read loop:

    while read -r Server User Password
    do
       /usr/bin/ssh -n $User@$Server touch /home/user/file_name.txt
    done </path/to/file.list
    

    But you will be prompted for the password. You cannot pass the “Password” to ssh so I’d suggest storing passwordless ssh-keys and placing them on each host for the user you are connecting as. If you are running this command from a script you can ssh as these users on each host by placing your public key in the user’s ~/.ssh/authorized_keys (or authorized_keys2) file. If you have the ssh-copy-id command you could do this by:

    ssh-copy-id user@hostname 
    

    which would copy YOUR ssh-key to their authorized_keys file so you could then ssh as them. This is assuming you have permission but then again you have their password so what permission do you need?