Schedule the last day of every month

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
2
down vote

favorite












I read from an instruction to schedule a script on the last day of months




Note:

The astute reader might be wondering just how you would be able to set a command to execute on the last day of every month because you can’t set the dayofmonth value to cover every month. This problem has plagued Linux and Unix programmers, and has spawned quite a few different solutions. A common method is to add an if-then statement that uses the date command to check if tomorrow’s date is 01:



00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1


This checks every day at 12 noon to see if it's the last day of the month, and if so, cron runs the command.




enter image description here



How does [date +%d -d tomorrow = 01 ] work,

Is it correct to state then; command1










share|improve this question









New contributor




Sawajiri is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • Are you sure that's verbatim what it says? As written here it in fact doesn't work.
    – Michael Homer
    6 hours ago










  • I posted the snapshot.@MichaelHomer
    – Sawajiri
    6 hours ago










  • Thanks! I've fiddled with the formatting to make it match - it's still not quite right, but it is what the picture says.
    – Michael Homer
    6 hours ago






  • 1




    Missing ; endif?
    – danblack
    6 hours ago










  • It doesn't work. It contains syntax errors: No space after [ and no fi at the end. Also, % is special in crontabs.
    – Kusalananda
    1 hour ago















up vote
2
down vote

favorite












I read from an instruction to schedule a script on the last day of months




Note:

The astute reader might be wondering just how you would be able to set a command to execute on the last day of every month because you can’t set the dayofmonth value to cover every month. This problem has plagued Linux and Unix programmers, and has spawned quite a few different solutions. A common method is to add an if-then statement that uses the date command to check if tomorrow’s date is 01:



00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1


This checks every day at 12 noon to see if it's the last day of the month, and if so, cron runs the command.




enter image description here



How does [date +%d -d tomorrow = 01 ] work,

Is it correct to state then; command1










share|improve this question









New contributor




Sawajiri is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • Are you sure that's verbatim what it says? As written here it in fact doesn't work.
    – Michael Homer
    6 hours ago










  • I posted the snapshot.@MichaelHomer
    – Sawajiri
    6 hours ago










  • Thanks! I've fiddled with the formatting to make it match - it's still not quite right, but it is what the picture says.
    – Michael Homer
    6 hours ago






  • 1




    Missing ; endif?
    – danblack
    6 hours ago










  • It doesn't work. It contains syntax errors: No space after [ and no fi at the end. Also, % is special in crontabs.
    – Kusalananda
    1 hour ago













up vote
2
down vote

favorite









up vote
2
down vote

favorite











I read from an instruction to schedule a script on the last day of months




Note:

The astute reader might be wondering just how you would be able to set a command to execute on the last day of every month because you can’t set the dayofmonth value to cover every month. This problem has plagued Linux and Unix programmers, and has spawned quite a few different solutions. A common method is to add an if-then statement that uses the date command to check if tomorrow’s date is 01:



00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1


This checks every day at 12 noon to see if it's the last day of the month, and if so, cron runs the command.




enter image description here



How does [date +%d -d tomorrow = 01 ] work,

Is it correct to state then; command1










share|improve this question









New contributor




Sawajiri is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I read from an instruction to schedule a script on the last day of months




Note:

The astute reader might be wondering just how you would be able to set a command to execute on the last day of every month because you can’t set the dayofmonth value to cover every month. This problem has plagued Linux and Unix programmers, and has spawned quite a few different solutions. A common method is to add an if-then statement that uses the date command to check if tomorrow’s date is 01:



00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1


This checks every day at 12 noon to see if it's the last day of the month, and if so, cron runs the command.




enter image description here



How does [date +%d -d tomorrow = 01 ] work,

Is it correct to state then; command1







shell-script






share|improve this question









New contributor




Sawajiri is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Sawajiri is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 6 hours ago









Isaac

8,58111241




8,58111241






New contributor




Sawajiri is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 6 hours ago









Sawajiri

165




165




New contributor




Sawajiri is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Sawajiri is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Sawajiri is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











  • Are you sure that's verbatim what it says? As written here it in fact doesn't work.
    – Michael Homer
    6 hours ago










  • I posted the snapshot.@MichaelHomer
    – Sawajiri
    6 hours ago










  • Thanks! I've fiddled with the formatting to make it match - it's still not quite right, but it is what the picture says.
    – Michael Homer
    6 hours ago






  • 1




    Missing ; endif?
    – danblack
    6 hours ago










  • It doesn't work. It contains syntax errors: No space after [ and no fi at the end. Also, % is special in crontabs.
    – Kusalananda
    1 hour ago

















  • Are you sure that's verbatim what it says? As written here it in fact doesn't work.
    – Michael Homer
    6 hours ago










  • I posted the snapshot.@MichaelHomer
    – Sawajiri
    6 hours ago










  • Thanks! I've fiddled with the formatting to make it match - it's still not quite right, but it is what the picture says.
    – Michael Homer
    6 hours ago






  • 1




    Missing ; endif?
    – danblack
    6 hours ago










  • It doesn't work. It contains syntax errors: No space after [ and no fi at the end. Also, % is special in crontabs.
    – Kusalananda
    1 hour ago
















Are you sure that's verbatim what it says? As written here it in fact doesn't work.
– Michael Homer
6 hours ago




Are you sure that's verbatim what it says? As written here it in fact doesn't work.
– Michael Homer
6 hours ago












I posted the snapshot.@MichaelHomer
– Sawajiri
6 hours ago




I posted the snapshot.@MichaelHomer
– Sawajiri
6 hours ago












Thanks! I've fiddled with the formatting to make it match - it's still not quite right, but it is what the picture says.
– Michael Homer
6 hours ago




Thanks! I've fiddled with the formatting to make it match - it's still not quite right, but it is what the picture says.
– Michael Homer
6 hours ago




1




1




Missing ; endif?
– danblack
6 hours ago




Missing ; endif?
– danblack
6 hours ago












It doesn't work. It contains syntax errors: No space after [ and no fi at the end. Also, % is special in crontabs.
– Kusalananda
1 hour ago





It doesn't work. It contains syntax errors: No space after [ and no fi at the end. Also, % is special in crontabs.
– Kusalananda
1 hour ago











2 Answers
2






active

oldest

votes

















up vote
3
down vote



accepted










Assuming that the syntax errors are fixed, and the command reformulated slightly to be less verbose:



00 12 28-31 * * [ "$( date -d tomorrow +%d )" = "01" ] && command1


This runs date +%d -d tomorrow (assuming that it's GNU date that is used) to get tomorrow's date as a two-digit number. If the number is 01, then today is the last day of the month. In that case, the tests succeeds and command1 is executed. The job is run at noon on the days that could possibly be the last day of the month.



The original command:



00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1


This has a few issues:



  • No space after [.


  • % is special in cron job specifications and must be escaped as % (see man 5 crontab).

  • There is no final fi at the end that matches up with the if.





share|improve this answer






















  • The problem with using [ ... ] && command1 instead of if... is that on days that are not the last day of the month, the cron job will end with a non-zero exit status and that failure may have to be reported. Using [ "$(...)" != 01 ] || command1 is another way to avoid the problem.
    – Stéphane Chazelas
    32 mins ago











  • Another problem with the original code is the ; between then and command1.
    – Stéphane Chazelas
    30 mins ago

















up vote
0
down vote













That is a quote from the book "Linux Command Line and Shell Scripting Bible" by Richard Blum, Christine Bresnahan pp 442, Third Edition, John Wiley & Sons ©2015.



Yes, that is what it says, but that is wrong/incomplete:



  • Missing a closing fi.

  • Needs space between [ and the following `.

  • It is strongly recommended to use $(…) instead of `…`.

  • It is important that you use quotes around expansions like "$(…)"

  • There is an additional ; after then

With the changes listed, this becomes:



if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi


How do I know? (well, by experience ☺ ) but you can try Shellcheck. Paste the code from the book and it will show you the errors listed above plus a "missing shebang". An script without errors in Shellcheck is this:



#!/bin/sh
if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi


That site works because what was written is "shell code". That is a syntax that works in many shells. The only issue not mentioned is that it is assuming that the date command is the GNU date version. The one with a -d option that accepts tomorrow as a value (busybox has a -d option but doesn't understand tomorrow and BSD has a -d option but is not related to "display" of time).



One issue that shellcheck doesn't show is that it is better to set the format after all the options to date date -d tomorrow +'%d'.



And, if all it is going to be executed from cron is a shell script (script.sh), then, it would be a lot better to write all inside that shell script:



#!/bin/sh
if [ "$(date -d tomorrow +'%d')" = 01 ] ; then
echo "The command will be executed"
fi


In this case, the cron line would be quite simpler:



00 12 * * * script.sh


Or even better:



00 12 28-31 * * script.sh


That would run the script (which internally will check that the day is the last day of the month) only on the days 28, 29, 30 and 31. It makes no sense to run it any other day.



That assumes that the script is inside a directory that the PATH of cron (not the same as the user) has listed (not likely). So use this instead:



0 12 28-31 * * /path/to/script/script.sh


Additionally, if the script is external, you can test if it works on some date (without waiting to the end of the month to discover it doesn't work) by testing it with faketime:



$ faketime 2018/10/31 ./script.sh
Command will be executed.





share|improve this answer






















  • Strictly speaking ast-open date and busybox date now also support date -d date-specification though busybox date doesn't support tomorrow as a date specification. BSD date have a -d option but it's for something completely unrelated.
    – Stéphane Chazelas
    27 mins ago











  • date +%d -d tomorrow with that option after a non-option argument, won't work with ast-open date, and with GNU date, only if POSIXLY_CORRECT is not in the environment. date -d tomorrow +%d would avoid the problem.
    – Stéphane Chazelas
    24 mins ago










Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);






Sawajiri is a new contributor. Be nice, and check out our Code of Conduct.









 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f478335%2fschedule-the-last-day-of-every-month%23new-answer', 'question_page');

);

Post as a guest






























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
3
down vote



accepted










Assuming that the syntax errors are fixed, and the command reformulated slightly to be less verbose:



00 12 28-31 * * [ "$( date -d tomorrow +%d )" = "01" ] && command1


This runs date +%d -d tomorrow (assuming that it's GNU date that is used) to get tomorrow's date as a two-digit number. If the number is 01, then today is the last day of the month. In that case, the tests succeeds and command1 is executed. The job is run at noon on the days that could possibly be the last day of the month.



The original command:



00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1


This has a few issues:



  • No space after [.


  • % is special in cron job specifications and must be escaped as % (see man 5 crontab).

  • There is no final fi at the end that matches up with the if.





share|improve this answer






















  • The problem with using [ ... ] && command1 instead of if... is that on days that are not the last day of the month, the cron job will end with a non-zero exit status and that failure may have to be reported. Using [ "$(...)" != 01 ] || command1 is another way to avoid the problem.
    – Stéphane Chazelas
    32 mins ago











  • Another problem with the original code is the ; between then and command1.
    – Stéphane Chazelas
    30 mins ago














up vote
3
down vote



accepted










Assuming that the syntax errors are fixed, and the command reformulated slightly to be less verbose:



00 12 28-31 * * [ "$( date -d tomorrow +%d )" = "01" ] && command1


This runs date +%d -d tomorrow (assuming that it's GNU date that is used) to get tomorrow's date as a two-digit number. If the number is 01, then today is the last day of the month. In that case, the tests succeeds and command1 is executed. The job is run at noon on the days that could possibly be the last day of the month.



The original command:



00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1


This has a few issues:



  • No space after [.


  • % is special in cron job specifications and must be escaped as % (see man 5 crontab).

  • There is no final fi at the end that matches up with the if.





share|improve this answer






















  • The problem with using [ ... ] && command1 instead of if... is that on days that are not the last day of the month, the cron job will end with a non-zero exit status and that failure may have to be reported. Using [ "$(...)" != 01 ] || command1 is another way to avoid the problem.
    – Stéphane Chazelas
    32 mins ago











  • Another problem with the original code is the ; between then and command1.
    – Stéphane Chazelas
    30 mins ago












up vote
3
down vote



accepted







up vote
3
down vote



accepted






Assuming that the syntax errors are fixed, and the command reformulated slightly to be less verbose:



00 12 28-31 * * [ "$( date -d tomorrow +%d )" = "01" ] && command1


This runs date +%d -d tomorrow (assuming that it's GNU date that is used) to get tomorrow's date as a two-digit number. If the number is 01, then today is the last day of the month. In that case, the tests succeeds and command1 is executed. The job is run at noon on the days that could possibly be the last day of the month.



The original command:



00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1


This has a few issues:



  • No space after [.


  • % is special in cron job specifications and must be escaped as % (see man 5 crontab).

  • There is no final fi at the end that matches up with the if.





share|improve this answer














Assuming that the syntax errors are fixed, and the command reformulated slightly to be less verbose:



00 12 28-31 * * [ "$( date -d tomorrow +%d )" = "01" ] && command1


This runs date +%d -d tomorrow (assuming that it's GNU date that is used) to get tomorrow's date as a two-digit number. If the number is 01, then today is the last day of the month. In that case, the tests succeeds and command1 is executed. The job is run at noon on the days that could possibly be the last day of the month.



The original command:



00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1


This has a few issues:



  • No space after [.


  • % is special in cron job specifications and must be escaped as % (see man 5 crontab).

  • There is no final fi at the end that matches up with the if.






share|improve this answer














share|improve this answer



share|improve this answer








edited 40 mins ago

























answered 1 hour ago









Kusalananda

112k15216343




112k15216343











  • The problem with using [ ... ] && command1 instead of if... is that on days that are not the last day of the month, the cron job will end with a non-zero exit status and that failure may have to be reported. Using [ "$(...)" != 01 ] || command1 is another way to avoid the problem.
    – Stéphane Chazelas
    32 mins ago











  • Another problem with the original code is the ; between then and command1.
    – Stéphane Chazelas
    30 mins ago
















  • The problem with using [ ... ] && command1 instead of if... is that on days that are not the last day of the month, the cron job will end with a non-zero exit status and that failure may have to be reported. Using [ "$(...)" != 01 ] || command1 is another way to avoid the problem.
    – Stéphane Chazelas
    32 mins ago











  • Another problem with the original code is the ; between then and command1.
    – Stéphane Chazelas
    30 mins ago















The problem with using [ ... ] && command1 instead of if... is that on days that are not the last day of the month, the cron job will end with a non-zero exit status and that failure may have to be reported. Using [ "$(...)" != 01 ] || command1 is another way to avoid the problem.
– Stéphane Chazelas
32 mins ago





The problem with using [ ... ] && command1 instead of if... is that on days that are not the last day of the month, the cron job will end with a non-zero exit status and that failure may have to be reported. Using [ "$(...)" != 01 ] || command1 is another way to avoid the problem.
– Stéphane Chazelas
32 mins ago













Another problem with the original code is the ; between then and command1.
– Stéphane Chazelas
30 mins ago




Another problem with the original code is the ; between then and command1.
– Stéphane Chazelas
30 mins ago












up vote
0
down vote













That is a quote from the book "Linux Command Line and Shell Scripting Bible" by Richard Blum, Christine Bresnahan pp 442, Third Edition, John Wiley & Sons ©2015.



Yes, that is what it says, but that is wrong/incomplete:



  • Missing a closing fi.

  • Needs space between [ and the following `.

  • It is strongly recommended to use $(…) instead of `…`.

  • It is important that you use quotes around expansions like "$(…)"

  • There is an additional ; after then

With the changes listed, this becomes:



if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi


How do I know? (well, by experience ☺ ) but you can try Shellcheck. Paste the code from the book and it will show you the errors listed above plus a "missing shebang". An script without errors in Shellcheck is this:



#!/bin/sh
if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi


That site works because what was written is "shell code". That is a syntax that works in many shells. The only issue not mentioned is that it is assuming that the date command is the GNU date version. The one with a -d option that accepts tomorrow as a value (busybox has a -d option but doesn't understand tomorrow and BSD has a -d option but is not related to "display" of time).



One issue that shellcheck doesn't show is that it is better to set the format after all the options to date date -d tomorrow +'%d'.



And, if all it is going to be executed from cron is a shell script (script.sh), then, it would be a lot better to write all inside that shell script:



#!/bin/sh
if [ "$(date -d tomorrow +'%d')" = 01 ] ; then
echo "The command will be executed"
fi


In this case, the cron line would be quite simpler:



00 12 * * * script.sh


Or even better:



00 12 28-31 * * script.sh


That would run the script (which internally will check that the day is the last day of the month) only on the days 28, 29, 30 and 31. It makes no sense to run it any other day.



That assumes that the script is inside a directory that the PATH of cron (not the same as the user) has listed (not likely). So use this instead:



0 12 28-31 * * /path/to/script/script.sh


Additionally, if the script is external, you can test if it works on some date (without waiting to the end of the month to discover it doesn't work) by testing it with faketime:



$ faketime 2018/10/31 ./script.sh
Command will be executed.





share|improve this answer






















  • Strictly speaking ast-open date and busybox date now also support date -d date-specification though busybox date doesn't support tomorrow as a date specification. BSD date have a -d option but it's for something completely unrelated.
    – Stéphane Chazelas
    27 mins ago











  • date +%d -d tomorrow with that option after a non-option argument, won't work with ast-open date, and with GNU date, only if POSIXLY_CORRECT is not in the environment. date -d tomorrow +%d would avoid the problem.
    – Stéphane Chazelas
    24 mins ago














up vote
0
down vote













That is a quote from the book "Linux Command Line and Shell Scripting Bible" by Richard Blum, Christine Bresnahan pp 442, Third Edition, John Wiley & Sons ©2015.



Yes, that is what it says, but that is wrong/incomplete:



  • Missing a closing fi.

  • Needs space between [ and the following `.

  • It is strongly recommended to use $(…) instead of `…`.

  • It is important that you use quotes around expansions like "$(…)"

  • There is an additional ; after then

With the changes listed, this becomes:



if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi


How do I know? (well, by experience ☺ ) but you can try Shellcheck. Paste the code from the book and it will show you the errors listed above plus a "missing shebang". An script without errors in Shellcheck is this:



#!/bin/sh
if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi


That site works because what was written is "shell code". That is a syntax that works in many shells. The only issue not mentioned is that it is assuming that the date command is the GNU date version. The one with a -d option that accepts tomorrow as a value (busybox has a -d option but doesn't understand tomorrow and BSD has a -d option but is not related to "display" of time).



One issue that shellcheck doesn't show is that it is better to set the format after all the options to date date -d tomorrow +'%d'.



And, if all it is going to be executed from cron is a shell script (script.sh), then, it would be a lot better to write all inside that shell script:



#!/bin/sh
if [ "$(date -d tomorrow +'%d')" = 01 ] ; then
echo "The command will be executed"
fi


In this case, the cron line would be quite simpler:



00 12 * * * script.sh


Or even better:



00 12 28-31 * * script.sh


That would run the script (which internally will check that the day is the last day of the month) only on the days 28, 29, 30 and 31. It makes no sense to run it any other day.



That assumes that the script is inside a directory that the PATH of cron (not the same as the user) has listed (not likely). So use this instead:



0 12 28-31 * * /path/to/script/script.sh


Additionally, if the script is external, you can test if it works on some date (without waiting to the end of the month to discover it doesn't work) by testing it with faketime:



$ faketime 2018/10/31 ./script.sh
Command will be executed.





share|improve this answer






















  • Strictly speaking ast-open date and busybox date now also support date -d date-specification though busybox date doesn't support tomorrow as a date specification. BSD date have a -d option but it's for something completely unrelated.
    – Stéphane Chazelas
    27 mins ago











  • date +%d -d tomorrow with that option after a non-option argument, won't work with ast-open date, and with GNU date, only if POSIXLY_CORRECT is not in the environment. date -d tomorrow +%d would avoid the problem.
    – Stéphane Chazelas
    24 mins ago












up vote
0
down vote










up vote
0
down vote









That is a quote from the book "Linux Command Line and Shell Scripting Bible" by Richard Blum, Christine Bresnahan pp 442, Third Edition, John Wiley & Sons ©2015.



Yes, that is what it says, but that is wrong/incomplete:



  • Missing a closing fi.

  • Needs space between [ and the following `.

  • It is strongly recommended to use $(…) instead of `…`.

  • It is important that you use quotes around expansions like "$(…)"

  • There is an additional ; after then

With the changes listed, this becomes:



if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi


How do I know? (well, by experience ☺ ) but you can try Shellcheck. Paste the code from the book and it will show you the errors listed above plus a "missing shebang". An script without errors in Shellcheck is this:



#!/bin/sh
if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi


That site works because what was written is "shell code". That is a syntax that works in many shells. The only issue not mentioned is that it is assuming that the date command is the GNU date version. The one with a -d option that accepts tomorrow as a value (busybox has a -d option but doesn't understand tomorrow and BSD has a -d option but is not related to "display" of time).



One issue that shellcheck doesn't show is that it is better to set the format after all the options to date date -d tomorrow +'%d'.



And, if all it is going to be executed from cron is a shell script (script.sh), then, it would be a lot better to write all inside that shell script:



#!/bin/sh
if [ "$(date -d tomorrow +'%d')" = 01 ] ; then
echo "The command will be executed"
fi


In this case, the cron line would be quite simpler:



00 12 * * * script.sh


Or even better:



00 12 28-31 * * script.sh


That would run the script (which internally will check that the day is the last day of the month) only on the days 28, 29, 30 and 31. It makes no sense to run it any other day.



That assumes that the script is inside a directory that the PATH of cron (not the same as the user) has listed (not likely). So use this instead:



0 12 28-31 * * /path/to/script/script.sh


Additionally, if the script is external, you can test if it works on some date (without waiting to the end of the month to discover it doesn't work) by testing it with faketime:



$ faketime 2018/10/31 ./script.sh
Command will be executed.





share|improve this answer














That is a quote from the book "Linux Command Line and Shell Scripting Bible" by Richard Blum, Christine Bresnahan pp 442, Third Edition, John Wiley & Sons ©2015.



Yes, that is what it says, but that is wrong/incomplete:



  • Missing a closing fi.

  • Needs space between [ and the following `.

  • It is strongly recommended to use $(…) instead of `…`.

  • It is important that you use quotes around expansions like "$(…)"

  • There is an additional ; after then

With the changes listed, this becomes:



if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi


How do I know? (well, by experience ☺ ) but you can try Shellcheck. Paste the code from the book and it will show you the errors listed above plus a "missing shebang". An script without errors in Shellcheck is this:



#!/bin/sh
if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi


That site works because what was written is "shell code". That is a syntax that works in many shells. The only issue not mentioned is that it is assuming that the date command is the GNU date version. The one with a -d option that accepts tomorrow as a value (busybox has a -d option but doesn't understand tomorrow and BSD has a -d option but is not related to "display" of time).



One issue that shellcheck doesn't show is that it is better to set the format after all the options to date date -d tomorrow +'%d'.



And, if all it is going to be executed from cron is a shell script (script.sh), then, it would be a lot better to write all inside that shell script:



#!/bin/sh
if [ "$(date -d tomorrow +'%d')" = 01 ] ; then
echo "The command will be executed"
fi


In this case, the cron line would be quite simpler:



00 12 * * * script.sh


Or even better:



00 12 28-31 * * script.sh


That would run the script (which internally will check that the day is the last day of the month) only on the days 28, 29, 30 and 31. It makes no sense to run it any other day.



That assumes that the script is inside a directory that the PATH of cron (not the same as the user) has listed (not likely). So use this instead:



0 12 28-31 * * /path/to/script/script.sh


Additionally, if the script is external, you can test if it works on some date (without waiting to the end of the month to discover it doesn't work) by testing it with faketime:



$ faketime 2018/10/31 ./script.sh
Command will be executed.






share|improve this answer














share|improve this answer



share|improve this answer








edited 2 mins ago

























answered 29 mins ago









Isaac

8,58111241




8,58111241











  • Strictly speaking ast-open date and busybox date now also support date -d date-specification though busybox date doesn't support tomorrow as a date specification. BSD date have a -d option but it's for something completely unrelated.
    – Stéphane Chazelas
    27 mins ago











  • date +%d -d tomorrow with that option after a non-option argument, won't work with ast-open date, and with GNU date, only if POSIXLY_CORRECT is not in the environment. date -d tomorrow +%d would avoid the problem.
    – Stéphane Chazelas
    24 mins ago
















  • Strictly speaking ast-open date and busybox date now also support date -d date-specification though busybox date doesn't support tomorrow as a date specification. BSD date have a -d option but it's for something completely unrelated.
    – Stéphane Chazelas
    27 mins ago











  • date +%d -d tomorrow with that option after a non-option argument, won't work with ast-open date, and with GNU date, only if POSIXLY_CORRECT is not in the environment. date -d tomorrow +%d would avoid the problem.
    – Stéphane Chazelas
    24 mins ago















Strictly speaking ast-open date and busybox date now also support date -d date-specification though busybox date doesn't support tomorrow as a date specification. BSD date have a -d option but it's for something completely unrelated.
– Stéphane Chazelas
27 mins ago





Strictly speaking ast-open date and busybox date now also support date -d date-specification though busybox date doesn't support tomorrow as a date specification. BSD date have a -d option but it's for something completely unrelated.
– Stéphane Chazelas
27 mins ago













date +%d -d tomorrow with that option after a non-option argument, won't work with ast-open date, and with GNU date, only if POSIXLY_CORRECT is not in the environment. date -d tomorrow +%d would avoid the problem.
– Stéphane Chazelas
24 mins ago




date +%d -d tomorrow with that option after a non-option argument, won't work with ast-open date, and with GNU date, only if POSIXLY_CORRECT is not in the environment. date -d tomorrow +%d would avoid the problem.
– Stéphane Chazelas
24 mins ago










Sawajiri is a new contributor. Be nice, and check out our Code of Conduct.









 

draft saved


draft discarded


















Sawajiri is a new contributor. Be nice, and check out our Code of Conduct.












Sawajiri is a new contributor. Be nice, and check out our Code of Conduct.











Sawajiri is a new contributor. Be nice, and check out our Code of Conduct.













 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f478335%2fschedule-the-last-day-of-every-month%23new-answer', 'question_page');

);

Post as a guest













































































Comments

Popular posts from this blog

What does second last employer means? [closed]

List of Gilmore Girls characters

Confectionery