1

I have a bash script that takes a handful of files and sets them up for FTP to a site that processes the one of the setup files. We are looking to find away to have the other file go up on the first Monday of the month but I am not sure how to put that in the bash script. I have seen stuff around using crontab but the first part and the last part of the script would be exactly the same and could cause issues if we had 2 different scripts.

only putting in a part of the script that I'm looking at making the change to.

#!/bin/bash
...

e_file="/tmp/tmpemail.$(date +%s).txt"
file1='/usr/local/filename1'
file2='/usr/local/filename2'
relayserver='relay-server.example.com'

#ftp info
FTP_USER='ftpuser' #not the actual FTP User Name
FTP_DEST_PATH='/'

...

echo -e "Starting Tunnel and SFTP Process"
# make ssh tunnel for access to SFTP Site
ssh -L 9022:ftp.example.com:22 serviceaccount@$relay_server -Nf >/dev/null 2&>1
proc=`ps -ef | grep "ssh -L 9022\:ftp.example.com\:22" | awk '{print $2}'`

#checks to see if the tunnel opened correctly then proceeds to push to FTP Site
if [ "${proc}" != "" ]; then

    #looking for first monday, was thinking of first day but the crontab only runs on monday to friday
    ifStart=`date '+%d'`
    if [ $ifStart == 01 ]; then 

        echo -e "File 1 & File2 sent to FTP Site" >> $e_file
            $SFTP_CMD -oPort=9022 -b /dev/stdin $FTP_USER@localhost << END
        cd $FTP_DEST_PATH
        put $file1
        put $file2
        bye
END

    else

        echo -e "file 2 sent to FTP" >> $e_file
            $SFTP_CMD -oPort=9022 -b /dev/stdin $FTP_USER@localhost << END
        cd $FTP_DEST_PATH
        put $file2
        bye
END

    fi

    echo "killing ssh tunnel - $proc"
    kill $proc

else

...

I am looking to be pointed in the right direction of getting the if statement for the first Monday of the month where I have to comment located. Any ideas to get around this?

Added Note: This Script has to run every weekday of the month to upload the files to be processed.

9

I do not have time to read all the script but here is the idea: with date command get the name of the day in week:

we=$(LC_TIME=C date +%A)

(LC_TIME=C is used to get English name of the day of week)

and then get day in the month

dm=$(date +%d)

and then check if the day is less than 8 and day of week is Monday:

if [ "$we" = "Monday" ] && [ "$dm" -lt 8 ]
then 
.....
fi
  • 1
    it might be worth adding an LC_TIME=C environment variable/prefix before the call to date +%A, to ensure you get English names (or perhaps setting LC_TIME to an English language). – Jeff Schaller May 25 '18 at 0:40
  • @JeffSchaller, thank you, will edit my answer – Romeo Ninov May 25 '18 at 2:09
  • 2
    You only need to call date once using a process substitution: read we dm < <(date "+%A %d") – glenn jackman May 25 '18 at 2:12
  • 1
    @thebtm, no. This is the way to set variable only for execution of current command. – Romeo Ninov May 28 '18 at 17:18
  • 1
    I believe @thebtm has a good point; if LC_TIME is not already exported, then it will not be set for the call to date. Using a semicolon wouldn't help, either. Either export LC_TIME or set it inside the command substitution: we=$(LC_TIME=C date +%A) – Jeff Schaller May 29 '18 at 15:55
3

Put the script in question into your crontab:

0 1 * * 1 [[ "$(/bin/date +\%d)" -le 7 ]] && /path/to/script.sh

On every Monday at 0100, it will check to see if the date is less than or equal to the seventh, and if so, run the script.

Bonus to using this is it's very easy to reschedule for Tuesdays without having to edit the script.

  • 1
    You need to escape % in the crontab: date "+\%d" -- documented in crontab(5) – glenn jackman May 25 '18 at 2:13
  • Done and done; good catch. – DopeGhoti May 25 '18 at 15:32
2

You could have cron run a script on every Monday and have the script check whether the day of the month is 1 to 7.

This check can either be integrated in your main script or you can write a wrapper script so that you do not have to make this change to the main script so that it can run.

if [[ $(date +%d) =~ 0[1-7] ]]; then
    : run script
fi

Checking both day of week and day of month:

if [[ $(date +%w%d) =~ 10[1-7] ]]; then
    : run script
fi
  • double condition where it checks for if its the day is within the first week and if the day is a monday if [[ $(date +%d) =~ 0[1-7] -a $(date +%u) == 1 ]]? – thebtm May 24 '18 at 20:48
  • 1
    @thebtm No, -a is for [ ], not for [[ ]]. No need to call date twice. See my edit. – Hauke Laging May 24 '18 at 20:53
  • This Answer works too but the other one is easier to read for if/when others need to take over the script. Thank You for the info though. – thebtm May 24 '18 at 21:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.