Bash script to test if it's the first Monday of the month
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
Related videos on Youtube
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, 2022Comments
-
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 almost 6 yearsdouble 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 almost 6 yearsThis 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 almost 6 yearsit might be worth adding an
LC_TIME=C
environment variable/prefix before the call todate +%A
, to ensure you get English names (or perhaps setting LC_TIME to an English language). -
Atul Vekariya almost 6 years@JeffSchaller, thank you, will edit my answer
-
Angel Todorov almost 6 yearsYou only need to call date once using a process substitution:
read we dm < <(date "+%A %d")
-
Angel Todorov almost 6 yearsYou need to escape
%
in the crontab:date "+\%d"
-- documented incrontab(5)
-
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 almost 6 yearsDone and done; good catch.
-
thebtm almost 6 yearsdo you need a semicolon "
;
" after theLC_TIME=C
? -
Atul Vekariya almost 6 years@thebtm, no. This is the way to set variable only for execution of current command.
-
Jeff Schaller almost 6 yearsI 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 almost 6 yearsThe 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 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 almost 6 yearsRomeo, see also
%u
, specified by POSIX to be the day of the week as a decimal number. -
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. :)