How to schedule cronjob for every 45 days?

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











up vote
2
down vote

favorite












How to execute a shell script via a cronjob every 45 days?







share|improve this question

















  • 1




    Related: stackoverflow.com/q/8699075/8239155
    – Jesse_b
    May 9 at 14:41










  • Possible duplicate of problem with cron job for every 2 minutes
    – vfbsilva
    May 9 at 20:12










  • See my systemd based solution, if you are using a distribution with this init/service system
    – nwildner
    May 9 at 21:00










  • @vfbsilva which answer in that post would solve the 45-day question here?
    – Jeff Schaller
    May 10 at 1:36










  • @JeffSchaller third answer explains the meaning of each field and syntax
    – vfbsilva
    May 10 at 2:19














up vote
2
down vote

favorite












How to execute a shell script via a cronjob every 45 days?







share|improve this question

















  • 1




    Related: stackoverflow.com/q/8699075/8239155
    – Jesse_b
    May 9 at 14:41










  • Possible duplicate of problem with cron job for every 2 minutes
    – vfbsilva
    May 9 at 20:12










  • See my systemd based solution, if you are using a distribution with this init/service system
    – nwildner
    May 9 at 21:00










  • @vfbsilva which answer in that post would solve the 45-day question here?
    – Jeff Schaller
    May 10 at 1:36










  • @JeffSchaller third answer explains the meaning of each field and syntax
    – vfbsilva
    May 10 at 2:19












up vote
2
down vote

favorite









up vote
2
down vote

favorite











How to execute a shell script via a cronjob every 45 days?







share|improve this question













How to execute a shell script via a cronjob every 45 days?









share|improve this question












share|improve this question




share|improve this question








edited May 9 at 21:18









GAD3R

22.1k154891




22.1k154891









asked May 9 at 14:36









PRAKASH

272




272







  • 1




    Related: stackoverflow.com/q/8699075/8239155
    – Jesse_b
    May 9 at 14:41










  • Possible duplicate of problem with cron job for every 2 minutes
    – vfbsilva
    May 9 at 20:12










  • See my systemd based solution, if you are using a distribution with this init/service system
    – nwildner
    May 9 at 21:00










  • @vfbsilva which answer in that post would solve the 45-day question here?
    – Jeff Schaller
    May 10 at 1:36










  • @JeffSchaller third answer explains the meaning of each field and syntax
    – vfbsilva
    May 10 at 2:19












  • 1




    Related: stackoverflow.com/q/8699075/8239155
    – Jesse_b
    May 9 at 14:41










  • Possible duplicate of problem with cron job for every 2 minutes
    – vfbsilva
    May 9 at 20:12










  • See my systemd based solution, if you are using a distribution with this init/service system
    – nwildner
    May 9 at 21:00










  • @vfbsilva which answer in that post would solve the 45-day question here?
    – Jeff Schaller
    May 10 at 1:36










  • @JeffSchaller third answer explains the meaning of each field and syntax
    – vfbsilva
    May 10 at 2:19







1




1




Related: stackoverflow.com/q/8699075/8239155
– Jesse_b
May 9 at 14:41




Related: stackoverflow.com/q/8699075/8239155
– Jesse_b
May 9 at 14:41












Possible duplicate of problem with cron job for every 2 minutes
– vfbsilva
May 9 at 20:12




Possible duplicate of problem with cron job for every 2 minutes
– vfbsilva
May 9 at 20:12












See my systemd based solution, if you are using a distribution with this init/service system
– nwildner
May 9 at 21:00




See my systemd based solution, if you are using a distribution with this init/service system
– nwildner
May 9 at 21:00












@vfbsilva which answer in that post would solve the 45-day question here?
– Jeff Schaller
May 10 at 1:36




@vfbsilva which answer in that post would solve the 45-day question here?
– Jeff Schaller
May 10 at 1:36












@JeffSchaller third answer explains the meaning of each field and syntax
– vfbsilva
May 10 at 2:19




@JeffSchaller third answer explains the meaning of each field and syntax
– vfbsilva
May 10 at 2:19










4 Answers
4






active

oldest

votes

















up vote
2
down vote



accepted










If you don't need exactly 45 days, but "one and a half months" will do, then a straightforward method would be to run at the beginning of the month every three months, and at the middle of the next month after each of those:



0 12 1 1,4,7,10 * /path/to/script
0 12 16 2,5,8,11 * /path/to/script


For general arbitrary intervals, the other answers are obviously better, but 45 days sounds like it's based on the length of a month anyway. Human users might also be more used to something happening in the beginning or the middle of a month, instead of seeing the exact date drift a day or two each time.






share|improve this answer




























    up vote
    5
    down vote













    Since cron doesn't support a simple, direct translation of that requirement, I would approach it with a timestamp file and a daily cron job:



    0 0 * * * /path/to/wrapper/script/below.sh


    the wrapper script:



    #!/bin/bash
    timestampfile=/var/run/this-job/timetampfile

    # exit now if it hasn't been 45 days
    ((
    $(date +%s) - $(stat -c %Z "$timestampfile")
    <
    (45 * 24 * 60 * 60)
    )) && exit 0

    touch "$timestampfile"
    : run real script here


    This runs several risks:



    • someone deleting the timestamp file

    • someone touching the timestamp file (for better or for worse)

    • leaving it non-obvious from the cron job entry that the actual script runs every 45 days





    share|improve this answer























    • Alternatively, invert the condition so the main branch of the if can exit the script when it's not going to do anything. That'll make it easier to stick the test to the script itself.
      – ilkkachu
      May 9 at 20:05










    • That's a great suggestion, @ilkkachu; thank you! I've incorporated it.
      – Jeff Schaller
      May 9 at 20:11

















    up vote
    4
    down vote













    Based on this answer on stack overflow, you could accomplish this with the following syntax:



    00 12 * * * test $(( $(date +%s)/24/60/60%45 )) = 20 && your_script


    This job will run every day at noon. It then calculates the modulo of the number of days from epoch and tests if it is equal to the modulo you specify. In this case I have specified 20 which would make it evaluate to true for today (2018-05-09 in between 00:00 GMT and 23:59 GMT), then 45 days from today, etc. You can calculate/test with the following:



    $ echo $(( $(date +%s)/24/60/60%45 ))
    20
    $ echo $(( $(date -d '+45 days' +%s)/24/60/60%45 ))
    20
    $ echo $(( $(date -d '+44 days' +%s)/24/60/60%45 ))
    19


    (beware that if you're not in a UTC timezone, you may have to take the hour of the day into account).






    share|improve this answer






























      up vote
      2
      down vote













      Alternative solution: systemd is eating all parts of the Linux system. With this in mind, it now has a timer unit that can be related to a service unit of the same name to create a schedule and mimic anacron. Example:



      Service. We will call it foo and it will run your script /home/user/foo.sh. When working with timers your service unit does not need to have the [Install] section:



      /etc/systemd/system/foo.service

      [Unit]
      Description=My foo script

      [Service]
      Type=simple
      ExecStart=/home/user/foo.sh


      Timer. This is the special unit that will handle time schedule:



      /etc/systemd/system/foo.timer

      [Unit]
      Description=Run foo every 45 days and on boot
      Persistent=true

      [Timer]
      OnBootSec=15min
      OnUnitActiveSec=45d

      [Install]
      WantedBy=multi-user.target


      Taking a look at the [Timer] section, your script will run 15 minutes after boot(you can remove this), and each 45 days. The Persistent= parameter means that even after rebooting the schedule will persist to disk and not be restarted.



      And then, enable both units:



      systemctl enable foo.service
      systemctl enable foo.timer


      You may not like systemd, but this is a quick solution to problems with schedule and cron.



      Further Reading:



      • systemd - Timer units that mimic anacron behaviour

      • systemd/Timers - Arch Linux Wiki





      share|improve this answer























      • With your average Linux box having to reboot every other week or so to apply kernel/libc/... security updates, that is very unlikely to have that script run every 45 days.
        – Stéphane Chazelas
        May 10 at 10:57










      • I agree, and that's why i used the Persistent= parameter on my answer. Not everyone do live kernel patching(neither have the resources to pay such tools), to make servers "rebootless".
        – nwildner
        May 10 at 12:35










      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
      );



      );








       

      draft saved


      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f442792%2fhow-to-schedule-cronjob-for-every-45-days%23new-answer', 'question_page');

      );

      Post as a guest






























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      2
      down vote



      accepted










      If you don't need exactly 45 days, but "one and a half months" will do, then a straightforward method would be to run at the beginning of the month every three months, and at the middle of the next month after each of those:



      0 12 1 1,4,7,10 * /path/to/script
      0 12 16 2,5,8,11 * /path/to/script


      For general arbitrary intervals, the other answers are obviously better, but 45 days sounds like it's based on the length of a month anyway. Human users might also be more used to something happening in the beginning or the middle of a month, instead of seeing the exact date drift a day or two each time.






      share|improve this answer

























        up vote
        2
        down vote



        accepted










        If you don't need exactly 45 days, but "one and a half months" will do, then a straightforward method would be to run at the beginning of the month every three months, and at the middle of the next month after each of those:



        0 12 1 1,4,7,10 * /path/to/script
        0 12 16 2,5,8,11 * /path/to/script


        For general arbitrary intervals, the other answers are obviously better, but 45 days sounds like it's based on the length of a month anyway. Human users might also be more used to something happening in the beginning or the middle of a month, instead of seeing the exact date drift a day or two each time.






        share|improve this answer























          up vote
          2
          down vote



          accepted







          up vote
          2
          down vote



          accepted






          If you don't need exactly 45 days, but "one and a half months" will do, then a straightforward method would be to run at the beginning of the month every three months, and at the middle of the next month after each of those:



          0 12 1 1,4,7,10 * /path/to/script
          0 12 16 2,5,8,11 * /path/to/script


          For general arbitrary intervals, the other answers are obviously better, but 45 days sounds like it's based on the length of a month anyway. Human users might also be more used to something happening in the beginning or the middle of a month, instead of seeing the exact date drift a day or two each time.






          share|improve this answer













          If you don't need exactly 45 days, but "one and a half months" will do, then a straightforward method would be to run at the beginning of the month every three months, and at the middle of the next month after each of those:



          0 12 1 1,4,7,10 * /path/to/script
          0 12 16 2,5,8,11 * /path/to/script


          For general arbitrary intervals, the other answers are obviously better, but 45 days sounds like it's based on the length of a month anyway. Human users might also be more used to something happening in the beginning or the middle of a month, instead of seeing the exact date drift a day or two each time.







          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered May 9 at 20:17









          ilkkachu

          48.1k669133




          48.1k669133






















              up vote
              5
              down vote













              Since cron doesn't support a simple, direct translation of that requirement, I would approach it with a timestamp file and a daily cron job:



              0 0 * * * /path/to/wrapper/script/below.sh


              the wrapper script:



              #!/bin/bash
              timestampfile=/var/run/this-job/timetampfile

              # exit now if it hasn't been 45 days
              ((
              $(date +%s) - $(stat -c %Z "$timestampfile")
              <
              (45 * 24 * 60 * 60)
              )) && exit 0

              touch "$timestampfile"
              : run real script here


              This runs several risks:



              • someone deleting the timestamp file

              • someone touching the timestamp file (for better or for worse)

              • leaving it non-obvious from the cron job entry that the actual script runs every 45 days





              share|improve this answer























              • Alternatively, invert the condition so the main branch of the if can exit the script when it's not going to do anything. That'll make it easier to stick the test to the script itself.
                – ilkkachu
                May 9 at 20:05










              • That's a great suggestion, @ilkkachu; thank you! I've incorporated it.
                – Jeff Schaller
                May 9 at 20:11














              up vote
              5
              down vote













              Since cron doesn't support a simple, direct translation of that requirement, I would approach it with a timestamp file and a daily cron job:



              0 0 * * * /path/to/wrapper/script/below.sh


              the wrapper script:



              #!/bin/bash
              timestampfile=/var/run/this-job/timetampfile

              # exit now if it hasn't been 45 days
              ((
              $(date +%s) - $(stat -c %Z "$timestampfile")
              <
              (45 * 24 * 60 * 60)
              )) && exit 0

              touch "$timestampfile"
              : run real script here


              This runs several risks:



              • someone deleting the timestamp file

              • someone touching the timestamp file (for better or for worse)

              • leaving it non-obvious from the cron job entry that the actual script runs every 45 days





              share|improve this answer























              • Alternatively, invert the condition so the main branch of the if can exit the script when it's not going to do anything. That'll make it easier to stick the test to the script itself.
                – ilkkachu
                May 9 at 20:05










              • That's a great suggestion, @ilkkachu; thank you! I've incorporated it.
                – Jeff Schaller
                May 9 at 20:11












              up vote
              5
              down vote










              up vote
              5
              down vote









              Since cron doesn't support a simple, direct translation of that requirement, I would approach it with a timestamp file and a daily cron job:



              0 0 * * * /path/to/wrapper/script/below.sh


              the wrapper script:



              #!/bin/bash
              timestampfile=/var/run/this-job/timetampfile

              # exit now if it hasn't been 45 days
              ((
              $(date +%s) - $(stat -c %Z "$timestampfile")
              <
              (45 * 24 * 60 * 60)
              )) && exit 0

              touch "$timestampfile"
              : run real script here


              This runs several risks:



              • someone deleting the timestamp file

              • someone touching the timestamp file (for better or for worse)

              • leaving it non-obvious from the cron job entry that the actual script runs every 45 days





              share|improve this answer















              Since cron doesn't support a simple, direct translation of that requirement, I would approach it with a timestamp file and a daily cron job:



              0 0 * * * /path/to/wrapper/script/below.sh


              the wrapper script:



              #!/bin/bash
              timestampfile=/var/run/this-job/timetampfile

              # exit now if it hasn't been 45 days
              ((
              $(date +%s) - $(stat -c %Z "$timestampfile")
              <
              (45 * 24 * 60 * 60)
              )) && exit 0

              touch "$timestampfile"
              : run real script here


              This runs several risks:



              • someone deleting the timestamp file

              • someone touching the timestamp file (for better or for worse)

              • leaving it non-obvious from the cron job entry that the actual script runs every 45 days






              share|improve this answer















              share|improve this answer



              share|improve this answer








              edited May 9 at 20:11


























              answered May 9 at 15:09









              Jeff Schaller

              31.1k846105




              31.1k846105











              • Alternatively, invert the condition so the main branch of the if can exit the script when it's not going to do anything. That'll make it easier to stick the test to the script itself.
                – ilkkachu
                May 9 at 20:05










              • That's a great suggestion, @ilkkachu; thank you! I've incorporated it.
                – Jeff Schaller
                May 9 at 20:11
















              • Alternatively, invert the condition so the main branch of the if can exit the script when it's not going to do anything. That'll make it easier to stick the test to the script itself.
                – ilkkachu
                May 9 at 20:05










              • That's a great suggestion, @ilkkachu; thank you! I've incorporated it.
                – Jeff Schaller
                May 9 at 20:11















              Alternatively, invert the condition so the main branch of the if can exit the script when it's not going to do anything. That'll make it easier to stick the test to the script itself.
              – ilkkachu
              May 9 at 20:05




              Alternatively, invert the condition so the main branch of the if can exit the script when it's not going to do anything. That'll make it easier to stick the test to the script itself.
              – ilkkachu
              May 9 at 20:05












              That's a great suggestion, @ilkkachu; thank you! I've incorporated it.
              – Jeff Schaller
              May 9 at 20:11




              That's a great suggestion, @ilkkachu; thank you! I've incorporated it.
              – Jeff Schaller
              May 9 at 20:11










              up vote
              4
              down vote













              Based on this answer on stack overflow, you could accomplish this with the following syntax:



              00 12 * * * test $(( $(date +%s)/24/60/60%45 )) = 20 && your_script


              This job will run every day at noon. It then calculates the modulo of the number of days from epoch and tests if it is equal to the modulo you specify. In this case I have specified 20 which would make it evaluate to true for today (2018-05-09 in between 00:00 GMT and 23:59 GMT), then 45 days from today, etc. You can calculate/test with the following:



              $ echo $(( $(date +%s)/24/60/60%45 ))
              20
              $ echo $(( $(date -d '+45 days' +%s)/24/60/60%45 ))
              20
              $ echo $(( $(date -d '+44 days' +%s)/24/60/60%45 ))
              19


              (beware that if you're not in a UTC timezone, you may have to take the hour of the day into account).






              share|improve this answer



























                up vote
                4
                down vote













                Based on this answer on stack overflow, you could accomplish this with the following syntax:



                00 12 * * * test $(( $(date +%s)/24/60/60%45 )) = 20 && your_script


                This job will run every day at noon. It then calculates the modulo of the number of days from epoch and tests if it is equal to the modulo you specify. In this case I have specified 20 which would make it evaluate to true for today (2018-05-09 in between 00:00 GMT and 23:59 GMT), then 45 days from today, etc. You can calculate/test with the following:



                $ echo $(( $(date +%s)/24/60/60%45 ))
                20
                $ echo $(( $(date -d '+45 days' +%s)/24/60/60%45 ))
                20
                $ echo $(( $(date -d '+44 days' +%s)/24/60/60%45 ))
                19


                (beware that if you're not in a UTC timezone, you may have to take the hour of the day into account).






                share|improve this answer

























                  up vote
                  4
                  down vote










                  up vote
                  4
                  down vote









                  Based on this answer on stack overflow, you could accomplish this with the following syntax:



                  00 12 * * * test $(( $(date +%s)/24/60/60%45 )) = 20 && your_script


                  This job will run every day at noon. It then calculates the modulo of the number of days from epoch and tests if it is equal to the modulo you specify. In this case I have specified 20 which would make it evaluate to true for today (2018-05-09 in between 00:00 GMT and 23:59 GMT), then 45 days from today, etc. You can calculate/test with the following:



                  $ echo $(( $(date +%s)/24/60/60%45 ))
                  20
                  $ echo $(( $(date -d '+45 days' +%s)/24/60/60%45 ))
                  20
                  $ echo $(( $(date -d '+44 days' +%s)/24/60/60%45 ))
                  19


                  (beware that if you're not in a UTC timezone, you may have to take the hour of the day into account).






                  share|improve this answer















                  Based on this answer on stack overflow, you could accomplish this with the following syntax:



                  00 12 * * * test $(( $(date +%s)/24/60/60%45 )) = 20 && your_script


                  This job will run every day at noon. It then calculates the modulo of the number of days from epoch and tests if it is equal to the modulo you specify. In this case I have specified 20 which would make it evaluate to true for today (2018-05-09 in between 00:00 GMT and 23:59 GMT), then 45 days from today, etc. You can calculate/test with the following:



                  $ echo $(( $(date +%s)/24/60/60%45 ))
                  20
                  $ echo $(( $(date -d '+45 days' +%s)/24/60/60%45 ))
                  20
                  $ echo $(( $(date -d '+44 days' +%s)/24/60/60%45 ))
                  19


                  (beware that if you're not in a UTC timezone, you may have to take the hour of the day into account).







                  share|improve this answer















                  share|improve this answer



                  share|improve this answer








                  edited May 10 at 11:01









                  ilkkachu

                  48.1k669133




                  48.1k669133











                  answered May 9 at 14:50









                  Jesse_b

                  10.3k22658




                  10.3k22658




















                      up vote
                      2
                      down vote













                      Alternative solution: systemd is eating all parts of the Linux system. With this in mind, it now has a timer unit that can be related to a service unit of the same name to create a schedule and mimic anacron. Example:



                      Service. We will call it foo and it will run your script /home/user/foo.sh. When working with timers your service unit does not need to have the [Install] section:



                      /etc/systemd/system/foo.service

                      [Unit]
                      Description=My foo script

                      [Service]
                      Type=simple
                      ExecStart=/home/user/foo.sh


                      Timer. This is the special unit that will handle time schedule:



                      /etc/systemd/system/foo.timer

                      [Unit]
                      Description=Run foo every 45 days and on boot
                      Persistent=true

                      [Timer]
                      OnBootSec=15min
                      OnUnitActiveSec=45d

                      [Install]
                      WantedBy=multi-user.target


                      Taking a look at the [Timer] section, your script will run 15 minutes after boot(you can remove this), and each 45 days. The Persistent= parameter means that even after rebooting the schedule will persist to disk and not be restarted.



                      And then, enable both units:



                      systemctl enable foo.service
                      systemctl enable foo.timer


                      You may not like systemd, but this is a quick solution to problems with schedule and cron.



                      Further Reading:



                      • systemd - Timer units that mimic anacron behaviour

                      • systemd/Timers - Arch Linux Wiki





                      share|improve this answer























                      • With your average Linux box having to reboot every other week or so to apply kernel/libc/... security updates, that is very unlikely to have that script run every 45 days.
                        – Stéphane Chazelas
                        May 10 at 10:57










                      • I agree, and that's why i used the Persistent= parameter on my answer. Not everyone do live kernel patching(neither have the resources to pay such tools), to make servers "rebootless".
                        – nwildner
                        May 10 at 12:35














                      up vote
                      2
                      down vote













                      Alternative solution: systemd is eating all parts of the Linux system. With this in mind, it now has a timer unit that can be related to a service unit of the same name to create a schedule and mimic anacron. Example:



                      Service. We will call it foo and it will run your script /home/user/foo.sh. When working with timers your service unit does not need to have the [Install] section:



                      /etc/systemd/system/foo.service

                      [Unit]
                      Description=My foo script

                      [Service]
                      Type=simple
                      ExecStart=/home/user/foo.sh


                      Timer. This is the special unit that will handle time schedule:



                      /etc/systemd/system/foo.timer

                      [Unit]
                      Description=Run foo every 45 days and on boot
                      Persistent=true

                      [Timer]
                      OnBootSec=15min
                      OnUnitActiveSec=45d

                      [Install]
                      WantedBy=multi-user.target


                      Taking a look at the [Timer] section, your script will run 15 minutes after boot(you can remove this), and each 45 days. The Persistent= parameter means that even after rebooting the schedule will persist to disk and not be restarted.



                      And then, enable both units:



                      systemctl enable foo.service
                      systemctl enable foo.timer


                      You may not like systemd, but this is a quick solution to problems with schedule and cron.



                      Further Reading:



                      • systemd - Timer units that mimic anacron behaviour

                      • systemd/Timers - Arch Linux Wiki





                      share|improve this answer























                      • With your average Linux box having to reboot every other week or so to apply kernel/libc/... security updates, that is very unlikely to have that script run every 45 days.
                        – Stéphane Chazelas
                        May 10 at 10:57










                      • I agree, and that's why i used the Persistent= parameter on my answer. Not everyone do live kernel patching(neither have the resources to pay such tools), to make servers "rebootless".
                        – nwildner
                        May 10 at 12:35












                      up vote
                      2
                      down vote










                      up vote
                      2
                      down vote









                      Alternative solution: systemd is eating all parts of the Linux system. With this in mind, it now has a timer unit that can be related to a service unit of the same name to create a schedule and mimic anacron. Example:



                      Service. We will call it foo and it will run your script /home/user/foo.sh. When working with timers your service unit does not need to have the [Install] section:



                      /etc/systemd/system/foo.service

                      [Unit]
                      Description=My foo script

                      [Service]
                      Type=simple
                      ExecStart=/home/user/foo.sh


                      Timer. This is the special unit that will handle time schedule:



                      /etc/systemd/system/foo.timer

                      [Unit]
                      Description=Run foo every 45 days and on boot
                      Persistent=true

                      [Timer]
                      OnBootSec=15min
                      OnUnitActiveSec=45d

                      [Install]
                      WantedBy=multi-user.target


                      Taking a look at the [Timer] section, your script will run 15 minutes after boot(you can remove this), and each 45 days. The Persistent= parameter means that even after rebooting the schedule will persist to disk and not be restarted.



                      And then, enable both units:



                      systemctl enable foo.service
                      systemctl enable foo.timer


                      You may not like systemd, but this is a quick solution to problems with schedule and cron.



                      Further Reading:



                      • systemd - Timer units that mimic anacron behaviour

                      • systemd/Timers - Arch Linux Wiki





                      share|improve this answer















                      Alternative solution: systemd is eating all parts of the Linux system. With this in mind, it now has a timer unit that can be related to a service unit of the same name to create a schedule and mimic anacron. Example:



                      Service. We will call it foo and it will run your script /home/user/foo.sh. When working with timers your service unit does not need to have the [Install] section:



                      /etc/systemd/system/foo.service

                      [Unit]
                      Description=My foo script

                      [Service]
                      Type=simple
                      ExecStart=/home/user/foo.sh


                      Timer. This is the special unit that will handle time schedule:



                      /etc/systemd/system/foo.timer

                      [Unit]
                      Description=Run foo every 45 days and on boot
                      Persistent=true

                      [Timer]
                      OnBootSec=15min
                      OnUnitActiveSec=45d

                      [Install]
                      WantedBy=multi-user.target


                      Taking a look at the [Timer] section, your script will run 15 minutes after boot(you can remove this), and each 45 days. The Persistent= parameter means that even after rebooting the schedule will persist to disk and not be restarted.



                      And then, enable both units:



                      systemctl enable foo.service
                      systemctl enable foo.timer


                      You may not like systemd, but this is a quick solution to problems with schedule and cron.



                      Further Reading:



                      • systemd - Timer units that mimic anacron behaviour

                      • systemd/Timers - Arch Linux Wiki






                      share|improve this answer















                      share|improve this answer



                      share|improve this answer








                      edited May 10 at 10:52


























                      answered May 9 at 20:59









                      nwildner

                      13.2k13971




                      13.2k13971











                      • With your average Linux box having to reboot every other week or so to apply kernel/libc/... security updates, that is very unlikely to have that script run every 45 days.
                        – Stéphane Chazelas
                        May 10 at 10:57










                      • I agree, and that's why i used the Persistent= parameter on my answer. Not everyone do live kernel patching(neither have the resources to pay such tools), to make servers "rebootless".
                        – nwildner
                        May 10 at 12:35
















                      • With your average Linux box having to reboot every other week or so to apply kernel/libc/... security updates, that is very unlikely to have that script run every 45 days.
                        – Stéphane Chazelas
                        May 10 at 10:57










                      • I agree, and that's why i used the Persistent= parameter on my answer. Not everyone do live kernel patching(neither have the resources to pay such tools), to make servers "rebootless".
                        – nwildner
                        May 10 at 12:35















                      With your average Linux box having to reboot every other week or so to apply kernel/libc/... security updates, that is very unlikely to have that script run every 45 days.
                      – Stéphane Chazelas
                      May 10 at 10:57




                      With your average Linux box having to reboot every other week or so to apply kernel/libc/... security updates, that is very unlikely to have that script run every 45 days.
                      – Stéphane Chazelas
                      May 10 at 10:57












                      I agree, and that's why i used the Persistent= parameter on my answer. Not everyone do live kernel patching(neither have the resources to pay such tools), to make servers "rebootless".
                      – nwildner
                      May 10 at 12:35




                      I agree, and that's why i used the Persistent= parameter on my answer. Not everyone do live kernel patching(neither have the resources to pay such tools), to make servers "rebootless".
                      – nwildner
                      May 10 at 12:35












                       

                      draft saved


                      draft discarded


























                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f442792%2fhow-to-schedule-cronjob-for-every-45-days%23new-answer', 'question_page');

                      );

                      Post as a guest













































































                      Popular posts from this blog

                      Peggy Mitchell

                      Palaiologos

                      The Forum (Inglewood, California)