While loop not reading all files if ssh fails

The below while loop is in ksh on a SunOs server: SPARC-Enterprise 5.10
The ksh version is: Version M-11/16/88i

The intention of the below while loop is to read through a list of file names in files.txt and
delete each file from a server, one at a time. The delete works, the problem is that if a file
does not exist the loop exits instead of issuing the read for the next file. The first file name
in files.txt does not exist, purposely to allow testing the routine for file not present.

Interestingly if the ssh cmd is removed and replaced with the execution of a non-existent
script the loop does not exit, it reads all files in files.txt. Why does the loop exit when ssh
tries to delete a file not on the server? I have tried various versions of trap with no success.
There is no break or exit in the script, which contains only the while loop.
Thanks, Lee

#!/bin/ksh
USAGE=�usage: test.ksh�

Code:
while read InputRecord
do
  echo �Start�   This displays only once
 
  ssh  [this cmd issues a rm of a file from files.txt, this works] > $LOG/file.delete.log   The return code is �1� for file not found.
 
  <A rtn which greps file.delete.log for file not found and if so logs this fact.  This works>
 
  echo �** got here�  This simply tells me that after the first error control gets here and then 
  exits the loop.
done < $LOG/files.txt

why not paste the actual code? perhaps your pseudo-code is missing something important, like "set -e"

1 Like

Here is the code.

!/bin/ksh
#set -xv
USAGE="usage: test2.ksh"
 
# Set the environment variables
. /bill/adc/env.vars
. /bill/common/host/set.host.bat
 
# Set env vars
AdcIP=`grep ADCIPadr $DAY_DIR/ADC.Web.Server.cfg | awk '{ print $2}'`
DataDir=`grep ADCdataDir $DAY_DIR/ADC.Web.Server.cfg | awk '{ print $2}'`
ADCuid=`grep ADCuid $DAY_DIR/ADC.Web.Server.cfg | awk '{ print $2}'`
 
#--------------------------------------------------------------------------------------------------#
# DELETE the billing files from the web server                                                   #
#--------------------------------------------------------------------------------------------------#
 
echo `date` '    Start of delete routine' >> $AUD_DIR/app.log
 
while read InputRecord
do
   echo `date` '      Deleting file..............................: ' $InputRecord >> $AUD_DIR/app.log
 
   ssh -i $SSH_DIR/<ssh key> -b $SrcIP $ADCuid@$AdcIP "rm $DataDir/$InputRecord" > $LOG_DAY/delete.adc.bill.files.log 2>&1
 
   echo 'RC: ' $?
 
   echo 'IR: ' $InputRecord
done < $LOG_DAY/bill.files.pulled.lst

BUMP - Interested in knowing the answer to this

Through a LOT of trial and error and researching on the net I came across the below while loop
syntax just a little while ago, the first example below. I changed my while loop to match and it
works yet I do not understand why it works. The echo of $? after each ssh �rm� failure is 1 as
it should be because the files do not exit. I am testing the error condition for when a file does not
exist. I would like to understand the reason the syntax works. The previous while loop after the
first file rm failure had control go back to the read and then the script stopped; I used �set -xv�.
It was as if the �rm� failure triggered an EOF.

while IFS= read -r f <&3;
do
     #do something with "$f"
     rm -f "$f"
done 3< delete.txt
 
while IFS= read -r FileName <&3;
do
       echo `date` '      Deleting file..............................: ' $FileName >> $AUD_DIR/app.log
 
       ssh -i $SSH_DIR/m5kdom6.adc.webserver.pri -b $SrcIP $ADCuid@$AdcIP "rm $DataDir/$FileName" > $LOG_DAY/delete.adc.bill.files.log 2>&1
 
       echo 'RC: ' $?
done 3< $LOG_DAY/bill.files.pulled.lst

When you redirect into your while loop with <, you are redirecting stdin from that file.

ssh, an interactive application, tries to use stdin as your keyboard, eating all your lines.

Use ssh -n to avoid this problem.

2 Likes

I have successfully run the script in the original form with the -n parameter. I have also read more about it on the net. I appreciate your help.