I'm having trouble with some automated sftp pulls. I'm using expect inside bash scripts and spawning SFTP. Some times the expect seems bog down. I have tried to put sleeps in my code to give everything time to work before I move on to next step but I till continue to get issues. For example when the function removeFlagFiles is called a for loop is used to get the name of each flag file downloaded. The expect part of the loop is supposed to delete the flag file. I can watch the output and all of a sudden the interaction seems to slow way down and sometimes the file is not deleted. Can someone suggest better ways of doing this?
#!/bin/bash
#
# Author: Gene Osteen
# Date: 12/11/2014
# Description: Pull performant HUMA files directory(s) and flag file(s).
# Hard-coded directories that have to be in the current (running) directory.
FILTER="HUMA*.flag"
DOWNLOAD_DIR="/ftpdata/HUMA/incoming/HUMA.dir"
REMOTE_DIR=""
function pullDataFile {
echo "In pullDataFile" >> $4
echo "remote dir = $1"
echo "file name = $2"
echo "dir = $3"
echo "remote dir = $1 file name = $2 dir = $3\n" >> $4
maxiter=5
iter=1
filestate="trypull"
while [ $filestate = "trypull" ]
do
echo "================= Start SFTP pull of $2 iteration $iter ===================" >> $4
/usr/bin/expect<<EOF
spawn sftp somesftp@10.10.10.10
sleep 1
expect "(yes/no)?"
sleep 1
send "yes \r"
sleep 1
expect "password:"
sleep 1
send "somepassword\n"
sleep 1
expect "sftp>"
log_file $4
send "cd $1 \r"
expect "sftp>"
send "lcd $3 \r"
expect "sftp>"
send "get $2 \r"
expect {
#Check for progress, note does not work with all versions of SFTP
#If a match is found restart expect loop
-re "\[0-9]*%" {
set percent $expect_out(0,string)
#puts $logf "File transfer at $percent, continuing..."
exp_continue
}
#Check for common errors, by no means all of them
-re "Couldn't|(.*)disconnect|(.*)stalled" {
#puts $logf "Unable to transfer file"
exit 1
}
#OK continue
"sftp>" {
#puts $logf "File transfer completed"
}
}
log_file
send "quit \r"
EOF
sleep 3
if [ -f ./$3/$2 ]; then
echo "File ./$3/$2 Arrived" >> $4
filestate="Arrived"
else
echo "File ./$3/$2 HAS NOT ARRIVED" >> $4
iter=$[$iter+1]
if [ $iter -gt $maxiter ]; then
filestate="Too Many Tries"
else
sleep 10
fi
fi
done
if [ $filestate = "Arrived" ]; then
echo "chmod ./$3/$2 to 755" >> $4
chmod 775 ./$3/$2
# Below must be formatted with no leading white space
/usr/bin/expect<<EOF
spawn sftp somesftp@10.10.10.10
sleep 1
expect "(yes/no)?"
send "yes \r"
sleep 1
expect "password:"
send "somepassword\n"
sleep 1
expect "sftp>"
log_file $4
send "cd $1 \r"
expect "sftp>"
send "rm $2 \r"
expect "sftp>"
log_file
send "quit \r"
EOF
else
echo "Send Email" >> $4
#Send email when you can
fi
sleep 4
}
function removeFlagFiles {
echo "======================= Remove Flag Files =======================================\n\n" >> $1
for f in $FILTER;
do
echo "Remove $f" >> $1
delfile="$f"
delfile2="${delfile//\#/\\\#}"
echo "delfile2 = $delfile2"
echo "delfile = $f delfile2 = $v"
sleep 3
/usr/bin/expect<<EOF
spawn sftp somesftp@10.10.10.10
sleep 1
expect "(yes/no)?"
sleep 1
send "yes \r"
sleep 1
expect "password:"
sleep 1
send "somepassword\n"
expect "sftp>"
sleep 1
log_file $1
send "cd outgoing \r"
sleep 1
expect "sftp>"
send "rm $delfile2 \r"
sleep 1
expect "sftp>"
log_file
send "quit \r"
EOF
sleep 4
done
echo "======================= Finished Removing Flag Files =======================================\n\n\n" >> $1
}
function pullFlagFiles {
echo "======================== Pull existing flag files===========================================" >> $1
echo "Start of SFTP" >> $1
/usr/bin/expect<<EOF
spawn sftp somesftp@10.10.10.10
expect "(yes/no)?"
send "yes \r"
expect "password:"
send "somepassword\n"
expect "sftp>"
log_file $1
send "cd outgoing \r"
expect "sftp>"
send "get $FILTER \r"
expect "sftp>"
log_file
send "quit \r"
EOF
echo "======================== Finished Pulling existing flag files===========================================\n\n\n" >> $1
sleep 4
}
function processFiles {
for f in $FILTER;
do
echo "======================== Process File $f =================================\n" >> $1
arr=($(echo $f | tr "#" "\n"))
dir=${arr[@]:1:1}
fname=${arr[@]:2:2}
fname2="${fname/.flag/}"
remote_dir="outgoing/HUMA.dir/$dir"
echo $dir
echo $fname2
echo $remote_dir
newdir="$DOWNLOAD_DIR/$dir"
echo "newdir = $newdir"
echo "newdir = $newdir" >> $1
# Create the directory if it's not there already.
echo "Try to create $newdir"
echo "Try to create $newdir" >> $1
mkdir -p $newdir
status=$?
echo "status from mkdir $newdir = $status" >> $1
if [ -d $newdir ];
then
echo "$newdir exists."
echo "$newdir exists." >> $1
else
echo "File $newdir does not exist."
echo "File $newdir does not exist." >> $1
return
fi
chmod 775 $newdir
echo "Target Directory = $newdir\n" >> $1
# Get data file
pullDataFile $remote_dir $fname2 $dir $1
if [ -f $dir/$1 ];
then
echo "File $dir/$1 exists." >> $1
else
echo "File $dir/$1 does not exist." >> $1
fi
# Change the permission and Move the file into the directory where it's wanted.
chmod 775 $f
echo "mv $f $newdir" >> $1
mv $f $newdir
if [ -f $fname2 ];
then
echo "File $newdir/$fname2 exists." >> $1
else
echo "File $newdir/$$fname2 does not exist." >> $1
fi
echo "==================== Finished File $f ===========================================\n\n\n" >> $1
done
}
###################
####### MAIN ######
###################
cd /ftpdata/HUMA/incoming/HUMA.dir
DATE=`date +%Y%m%d`
echo "DATE = $DATE"
logfile="./Logs/ftp_log_$DATE.log"
echo "Log_file = $logfile"
if [ -f ./HUMA_running.txt ]
then
echo "Already running"
exit
fi
echo "Let's start"
touch HUMA_running.txt
echo "Start HUMA search : $(date)" >> $logfile
# Now do a full cycle of pull, rename, and process.
echo "pullFlagFiles" >> $logfile
pullFlagFiles $logfile
ls -l $FILTER > /dev/null 2>&1
if [ "$?" = "0" ]; then
removeFlagFiles $logfile
processFiles $logfile
else
echo "No files to process" >> $logfile
fi
echo "" >> $logfile
rm ./HUMA_running.txt