0

I have the below bash script set to run every hour via cron as the root user. The purpose of this script is to email us when files have been uploaded to our sftp server and send us the logins. Here is the script

    build_report()  {
    # This function builds the report header and gets the list of files

    #Get all the files under /home/SFTP
    local f=($( find "/home/SFTP" -type f | tr " " "_" ))

    echo
    echo "********************************************";
    echo "*************** FILE REPORT ****************";
    echo "********************************************";
    echo "****  SEARCHING THROUGH SFTP FOLDERS  ******";
    echo "********************************************";
    echo "* IF I FIND SOMETHING, I WILL LIST IT HERE *";
    echo "********************************************";
    echo "********************************************";
    echo "GENERATED ON $TIMESTAMP                     ";

    echo
    echo
    #Loop through all the files and list list them
    for i in " ${f[@]}"
    do
            echo $i
    done
    }

    sftp_log() {
    #This function checks the /var/log/auth.log file for sessions 

    echo "*****************Begin Access Log*********************"
    cat /var/log/auth.log|grep -E "interactive/pam"

    }

    TIMESTAMP=$(date)
    files=$(find "/home/SFTP" -type f | tr " " "_")

     #If there are files present create the report, email it and log we found something.
    #Else, log we didn't find anything 
    if [ "$files" != "" ]; then
            { build_report && sftp_log; } | awk '{print $0,"\n"}' | mail -s "report" user@ourdomain.com
             echo $TIMESTAMP " Files found. Email Sent">>filereport.log
    else
            echo $TIMESTAMP " No files found" >>filereport.log
    fi

    exit 0

The issue comes at 8 AM every day. Here is an example of what happens

7AM: Files are present. The report is sent correctly with the output of both functions.

8AM: Same files are present. The report is sent with only the output of the build_report function

9AM: Same files are present. The report is sent with only the output of the build_report function

10AM: Files still present (could be new files added, could be the same file). An email is sent with the output of both functions correctly and the login that occurred between 8-9 is now present.

I set the auth.log to rotate once a week to make sure there wasn't some kind of file rotation/file lock issue. Also, if there are files present at 7AM, we get a correct report then.

Any ideas? My bash scripting ability is crude at best, so any ideas are welcome

  • In line containing `build_report && sftp_log` sftp_log will only be invoked if build_report returns true. Without going into details why it returns false, try replacing && with semicolon, so that command reads: `build_report; sftp_log` and both functions should run. – Marko Živanović Feb 27 '15 at 20:17
  • OK, I will make the change and let you know what happens on Monday as this issue only occurs once a day at the same time and I can't reproduce it – SouperGrover Feb 27 '15 at 20:57
  • @MarkoŽivanović I tried your suggestion but hte same thing happened this morning - 7AM report came with file and access log present, 8 AM report came with only the file, 9AM report came with only the file, 10 AM report came with the file and access log – SouperGrover Mar 02 '15 at 18:04
  • I don't have FreeBSD system handy to check, but, maybe there is some race condition: maybe there is some scheduled job that rotates the files or some such and it executes at the same time as your script. This might cause your script to see intermediate state with some files missing due to rotation. – Marko Živanović Mar 02 '15 at 19:27
  • I thought file rotation/access may be an issue as well but I do not know how to verify this. Can you give me an idea? I set the auth.log file to rotate once a week via syslog and this is working fine. How can I check if files are locked/missing? – SouperGrover Mar 03 '15 at 00:32
  • I'd try logging the list of files in the directory. Something along the lines of `while (true); do sleep 10; date >> /tmp/files.log; ls -la >> /tmp/files.log; done`. This will add directory listing to the log file every 10 seconds. I'd start this from cron job a few minutes before the critical time and hope to catch something informative. Of course, `ls -la` could be accompanied by `lsof` and/or `ps ax` to log open files and running processes. – Marko Živanović Mar 03 '15 at 20:59
  • The parentheses around `(true)` are useless. – tripleee Mar 06 '15 at 12:44
  • I would add `head -n 2 /var/log/auth.log; tail -n 2 /var/log/auth.log` to get an idea of what's in the log file at the time the script runs. – tripleee Mar 06 '15 at 12:44
  • As an aside, collecting the output from `find` into a variable only to print the value of that variable is rather pointless. Just run the `find` command after the headers and have it print its output into the report. Somewhat similarly, `grep 'interactive/pam' /var/log/auth.log` avoids a completely [useless `cat`](http://porkmail.org/era/unix/award.html) and drops the (here) redundant `-E` flag. – tripleee Mar 06 '15 at 12:46

1 Answers1

0

Put an echo $BASH in to see what happens you may find that unless you're explicitly telling crown to use bash, it's using sh, and I'm not sure that appending [@] is in FreeBSD sh.

Chris Rees
  • 275
  • 1
  • 7
  • I can try this, but I am fairly certain it is using BASH because there was a function misbehaving until I explicitly added #!/usr/local/bin/bash to the top of the script – SouperGrover Mar 02 '15 at 18:06