Required help on a Generic File-watcher script

Hi All,

Good morning...

I have prepared a shell script which will monitor files in a certain folder and if available, SCP it to a destination path.

Now the challenge I'm facing is my script is currently SCP-ing to only a single destination path. Wherever different destination path is in the scenario, my script is failing.

I'm using 2 properties files.

  1. Files to Monitor
  2. File-watcher configuration (contains server name, incoming path, destination path, scp user name etc etc)

The script is as below:

#!/bin/ksh

### This is for reading File Watcher config file and SCP the files to certain server
# >> Author: Saps
# >> Dated: 09-FEB-2016
# >> Version: 0.1
#

##Variables
CONFIG_PATH=/path/to/config/file
CONFIG_FILE=gen.FileWatcher.config
FILES_TO_MONITOR=app.outFile.FileWatcher.properties
CURR_HOST_NM=`uname -n`
 . $CONFIG_PATH/$CONFIG_FILE 2>/dev/null
sleepAppTime=$appt
sleepFWTime=$fwt
sleepSCPTime=$scpt
PROD_HOST=$p1h
UAT_HOST=$u1h
SCP_USER_NM=$scpuser
DEST_PATH=$dfpath
SCP_HOST=$scph
compFilePath=$ifpath
vDate=`date +%d%m%y%H%M`
# endFileSize=0

###### FUNCTION CREATION ################
function fileWatcherConcept
{
  echo "[INFO - `date`] Starting file watcher process..."
  sleep $sleepFWTime
  while true
  do
    filePath=$ofpath
    echo "[INFO - `date`] File path is: $filePath"
    for fileName in $(cat $CONFIG_PATH/$FILES_TO_MONITOR)
    do
      echo "[INFO - `date`] Watching file: $fileName"
      if [ ! -s $filePath/$fileName ]
      then
        echo "[INFO - `date`] The file: $filePath/$fileName is not arrived yet... will check after $sleepFWTime secs."
        sleep $sleepFWTime
      else
        echo "[INFO - `date`] File arrival is in progress..."
        sleep $sleepAppTime
        startFileSize=`ls -l $filePath/$fileName|awk '{print $5}'`
        echo "[DEBUG - `date`] File Size of $fileName on arrival: $startFileSize"
        echo "[INFO - `date`] SCP not completed yet... will check after $sleepSCPTime secs. "
        sleep $sleepSCPTime
        endFileSize=`ls -l $filePath/$fileName|awk '{print $5}'`
        echo "[DEBUG - `date`] File Size of $fileName after $sleepSCPTime secs: $endFileSize"
        if [ $startFileSize -eq $endFileSize ]
        then
          echo "[INFO - `date`] << FILE SIZE >> matches: $endFileSize is final size."
          echo "[INFO - `date`] The file: $filePath/$fileName has arrived... "
          echo "[INFO - `date`] Initializing file transfer via SCP process..."
          # SCP script / command goes here. also used scp errorCode is 0 or not
          echo "[INFO - `date`] SCP Command in execution is: /usr/local/bin/scp -B -q $filePath/$fileName $SCP_USER_NM@$SCP_HOST:$DEST_PATH/$fileName"
          /usr/local/bin/scp -B -q $filePath/$fileName $SCP_USER_NM@$SCP_HOST:$DEST_PATH/$fileName
          # scpErrCode=0 #<-- for debug
          scpErrCode=$?
          if [ $scpErrCode -ne 0 ]
          then
            echo "[DEBUG - `date`] Error in SCP. Error Code: $scpErrCode"
          else
            echo "[INFO - `date`] SCP completed successfully..."
            echo "[INFO - `date`] Sending SCP Completion Flag..." 
            echo "[INFO - `date`] SCP Command in execution for .comp file is: /usr/local/bin/scp -B -q $compFilePath/$fileName.comp $SCP_USER_NM@$SCP_HOST:$DEST_PATH/$fileName.comp"
            /usr/local/bin/scp -B -q $compFilePath/$fileName.comp $SCP_USER_NM@$SCP_HOST:$DEST_PATH/$fileName.comp
            sleep $sleepAppTime
            # mv command to move files from out to archive dir with timestamp
            mv $filePath/$fileName $filePath/$fileName.ARCHIVE
            echo "[INFO - `date`] file has moved to archive folder."
          fi
        else
          continue;
        fi
        sleep $sleepFWTime
      fi
    done
  done
}


#### MAIN ######

if [ "$CURR_HOST_NM" != "$PROD_HOST" ]
then
  echo "[INFO - `date`] Current host is $CURR_HOST_NM"
  echo "[INFO - `date`] Loading UAT configuration..."
  ## function goes here
  # echo "function call for UAT" #<-- for debug purpose
  sleep $sleepAppTime
  fileWatcherConcept
elif [ "$CURR_HOST_NM" != "$UAT_HOST" ]
then
  echo "[INFO - `date`] Current host is $CURR_HOST_NM"
  echo "[INFO - `date`] Loading PROD configuration..."
  ## function goes here
  # echo "function call for PROD" #<-- for debug purpose
  sleep $sleepAppTime
  fileWatcherConcept
else
  echo "[ERROR - `date`] Either the server: $CURR_HOST_NM or the configuration is incorrect. Exiting..."
  exit 1
fi

# END of FW Script

The contents of gen.FileWatcher.config:

# This is file watcher config file for application out-directory
#

::server::
u1h=uat.server
p1h=prod.server

::scpHost::
scpuh=uat.server
scpph=prod.server

::userIDs::
scpuser=scpUserNM

::appIDs:: #<-- this area just added, if any concept can be implemented using application IDs
app1=xyz
app2=abc

::filesPath::
ofpath=/outgoing/file/path/out/dir
ifpath=/incoming/file/path/in/dir
dfpath=/scp/destination/file/path/xyz_out
# dfpath1=/scp/destination/file/path/xyz_out #<-- if any concept can be implemented
# dfpath2=/scp/destination/file/path/abc_out #<-- if any concept can be implemented

::sleepTimes::
appt=3
fwt=5
scpt=10

The contents of app.outFile.FileWatcher.properties:

file_name_1.DAT
file_name_2.DAT
file_name_3.DAT
file_name_4.DAT

All kind of suggestion is welcome to achieve this.

Please let me know how can "SCP to different file path" can be implemented.

Thanks in advance,
Saps.

I would approach the problem differently.
If you have control of the sending process then, have the sender put the data file in the temp directory, then put a job file in the requests directory.
The job file contains the instructions for what to do with the data file.
The job file extension is used to create separate job streams, in our instance priority.
This entire process is run as a cron job with whatever frequency you choose. We found that a long running process is too fragile, and you don't find out is not running or is hung up on something until an angry user arrives.
If you cannot have two files sent, then use 'fuser' to determine if the file is still in the process of being received, and if it is still in use, bypass it until the next iteration.

#!/bin/ksh                                                                      
PATH=/bin:/usr/bin:/usr/lib                                                     
BATCH=$1                                                                        
proc=$$                                                                         
if [ -r /u/email/$BATCH.pid ]                                                   
then                                                                            
        echo Previous job `cat /u/email/$BATCH.pid` is still running            
        exit                                                                    
fi                                                                              
echo $proc >/u/email/$BATCH.pid                                                 
cd /u/email                                                                     
list=`ls requests|grep $BATCH`                                                  
if [ "$list" != "" ]                                                            
        then                                                                    
        for request in $list                                                    
        do                                                                      
        fuser $request                                                          
        if [ $? != 0 ]                                                          
          then                                                                  
          req=`echo $request|cut -d"." -f1`                                     
          export req                                                            
          IFS="~"                                                               
          #cat requests/$request |read user email from subject memo attachments 
          cat requests/$request | read  user destination                        
          
          IFS=" "                                                               
          cd /u/email/temp                                                      
          #php emailstub.php $user $email "$subject" $memo $attachments         
          #or in your instance scp $req* $user@destination:/incoming            
          cd /u/email                                                           
          mv /u/email/temp/$req* done                                           
          mv /u/email/requests/$request done                                    
        fi                                                                      
        sleep 10                                                                
        done                                                                    
fi                                                                              
rm /u/email/$BATCH.pid