Bash script to test if it's the first Monday of the month

10,729

Solution 1

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

Solution 2

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.

Solution 3

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
Share:
10,729

Related videos on Youtube

thebtm
Author by

thebtm

I Code for fun, to learn and to make my life easier. I work in IT and it's fun and exciting job. I also like to do photography when im not coding or working. I shoot with a Canon Equipment during my down time. Hobbies: Coding, Photography, Video Games, spending time with my family.

Updated on September 18, 2022

Comments

  • thebtm
    thebtm over 1 year

    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.

  • thebtm
    thebtm almost 6 years
    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
    thebtm almost 6 years
    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.
  • Jeff Schaller
    Jeff Schaller almost 6 years
    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).
  • Atul Vekariya
    Atul Vekariya almost 6 years
    @JeffSchaller, thank you, will edit my answer
  • Angel Todorov
    Angel Todorov almost 6 years
    You only need to call date once using a process substitution: read we dm < <(date "+%A %d")
  • Angel Todorov
    Angel Todorov almost 6 years
    You need to escape % in the crontab: date "+\%d" -- documented in crontab(5)
  • Atul Vekariya
    Atul Vekariya almost 6 years
    @glennjackman, true. But my understanding is OP want to have the script as much as possible human readable. You construction is correct, faster than mine. But maybe will need more time to be understood by reader :)
  • Pankaj Goyal
    Pankaj Goyal almost 6 years
    Done and done; good catch.
  • thebtm
    thebtm almost 6 years
    do you need a semicolon ";" after the LC_TIME=C?
  • Atul Vekariya
    Atul Vekariya almost 6 years
    @thebtm, no. This is the way to set variable only for execution of current command.
  • Jeff Schaller
    Jeff Schaller almost 6 years
    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)
  • thebtm
    thebtm almost 6 years
    The RHEL 6 is set to EN-CA for language, the LC_TIME=C isn't needed but its good to know for when I am dealing with a system not set to EN-??.
  • Jeff Schaller
    Jeff Schaller almost 6 years
    @thebtm - you never know what your environment will set for you. It's important here because the value of %A will definitely change for different locales; other outputs such as %d are much less likely to be influenced by locale.
  • Jeff Schaller
    Jeff Schaller almost 6 years
    Romeo, see also %u, specified by POSIX to be the day of the week as a decimal number.
  • Atul Vekariya
    Atul Vekariya almost 6 years
    @JeffSchaller, I had idea about this also. But I try to create script more human readable and easy for support. :)