Use systemd timer instead of cron job

I'm working on putting my   cron   The job is migrated to the systemd timer. I have been using timers for many years, but generally speaking, my knowledge is only enough to support my current job. But in my research   systemd series   During the process, I found that the systemd timer has some very interesting capabilities.

Similar to cron jobs, the systemd timer can trigger events (shell scripts and programs) at specific time intervals, such as once a day or on a specific day of the month (perhaps only on Monday), or every 15 minutes during working hours from 8 a.m. to 6 p.m. Timers can also do some things that cron jobs cannot do. For example, the timer can trigger a script or program to execute after a certain event, such as startup, startup, completion of the last task, and even the completion of the last service unit called by the timer.

Timer for operating system maintenance

When Fedora or any system D-based distribution is installed on a new system, it will create multiple timers in the background of the Linux host as part of the system maintenance process. These timers trigger events to perform necessary daily maintenance tasks, such as updating the system database, cleaning temporary directories, rotating log files, and more.

As an example, I'll look at some timers on my main workstation by executing   systemctl status *timer   Command to display all timers on the host. The function of asterisk is the same as that of file wildcard, so this command will list all systemd timer units.

    [root@testvm1 ~]# systemctl status *timer
    ● mlocate-updatedb.timer - Updates mlocate database every day
         Loaded: loaded (/usr/lib/systemd/system/mlocate-updatedb.timer; enabled; vendor preset: enabled)
         Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
        Trigger: Fri 2020-06-05 00:00:00 EDT; 15h left
       Triggers: ● mlocate-updatedb.service
    Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Updates mlocate database every day.
    ● logrotate.timer - Daily rotation of log files
         Loaded: loaded (/usr/lib/systemd/system/logrotate.timer; enabled; vendor preset: enabled)
         Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
        Trigger: Fri 2020-06-05 00:00:00 EDT; 15h left
       Triggers: ● logrotate.service
           Docs: man:logrotate(8)
                 man:logrotate.conf(5)
    Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Daily rotation of log files.
    ● sysstat-summary.timer - Generate summary of yesterday's process accounting
         Loaded: loaded (/usr/lib/systemd/system/sysstat-summary.timer; enabled; vendor preset: enabled)
         Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
        Trigger: Fri 2020-06-05 00:07:00 EDT; 15h left
       Triggers: ● sysstat-summary.service
    Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Generate summary of yesterday's process accounting.
    ● fstrim.timer - Discard unused blocks once a week
         Loaded: loaded (/usr/lib/systemd/system/fstrim.timer; enabled; vendor preset: enabled)
         Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
        Trigger: Mon 2020-06-08 00:00:00 EDT; 3 days left
       Triggers: ● fstrim.service
           Docs: man:fstrim
    Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Discard unused blocks once a week.
    ● sysstat-collect.timer - Run system activity accounting tool every 10 minutes
         Loaded: loaded (/usr/lib/systemd/system/sysstat-collect.timer; enabled; vendor preset: enabled)
         Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
        Trigger: Thu 2020-06-04 08:50:00 EDT; 41s left
       Triggers: ● sysstat-collect.service
    Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Run system activity accounting tool every 10 minutes.
    ● dnf-makecache.timer - dnf makecache --timer
         Loaded: loaded (/usr/lib/systemd/system/dnf-makecache.timer; enabled; vendor preset: enabled)
         Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
        Trigger: Thu 2020-06-04 08:51:00 EDT; 1min 41s left
       Triggers: ● dnf-makecache.service
    Jun 02 08:02:33 testvm1.both.org systemd[1]: Started dnf makecache –timer.
    ● systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories
         Loaded: loaded (/usr/lib/systemd/system/systemd-tmpfiles-clean.timer; static; vendor preset: disabled)
         Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
        Trigger: Fri 2020-06-05 08:19:00 EDT; 23h left
       Triggers: ● systemd-tmpfiles-clean.service
           Docs: man:tmpfiles.d(5)
                 man:systemd-tmpfiles(8)
    Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Daily Cleanup of Temporary Directories.

Each timer has at least six lines of relevant information:

◈   The first line of the timer has a brief introduction to the name and purpose of the timer   The second line shows the status of the timer, whether it has been loaded, the full path of the timer unit file and the preset information. ◈   The third line indicates its active status, including the date and time when the timer was activated. ◈   The fourth line includes the date and time when the timer is next triggered and the approximate time from the trigger. ◈   The fifth line shows the name of the event or service triggered by the timer. ◈   Some (but not all) systemd unit files have guidelines for relevant documents. There are three timers in the output of my virtual machine with document guidance. This is a good (but not necessary) message. ◈   The last line is the log entry of the service instance that was recently triggered by the timer.

You may have some different timers, depending on your host.

Create a timer

Although we can deconstruct one or more existing timers to understand how they work, let's create our own   Service unit   And a timer to trigger it. To keep it simple, we'll use a fairly simple example. When we finish this experiment, it will be easier to understand the working principle of other timers and find out what they are doing.

First, create a simple service that runs basic things, such as   free   Command. For example, you may want to monitor free memory regularly. stay  / etc/systemd/system   Create the following directory   myMonitor.server   Unit file. It does not need to be an executable:

    # This service unit is for testing timer units
    # By David Both
    # Licensed under GPL V2
    #
    [Unit]
    Description=Logs system statistics to the systemd journal
    Wants=myMonitor.timer
    [Service]
    Type=oneshot
    ExecStart=/usr/bin/free
    [Install]
    WantedBy=multi-user.target

This is probably the simplest service unit you can create. Now let's look at the service status and test the service unit to ensure that it is as available as we expected.

    [root@testvm1 system]# systemctl status myMonitor.service
    ● myMonitor.service - Logs system statistics to the systemd journal
         Loaded: loaded (/etc/systemd/system/myMonitor.service; disabled; vendor preset: disabled)
         Active: inactive (dead)
    [root@testvm1 system]# systemctl start myMonitor.service
    [root@testvm1 system]#

Where is the output? By default, the standard output (STDOUT) of the systemd service unit executor is sent to the system log, which keeps records for viewing now or later (until a certain point in time). (in subsequent articles in this series, I will introduce the recording and retention policies of system logs). Specifically check the log of your service unit, and only for today- S   Options, i.e  -- since   An abbreviation that allows you to specify   journalctl   The time period for the tool search entry. This doesn't mean that you don't care about past results - in this case, there will be no past records - if your machine runs for a long time and accumulates a large number of logs, it can shorten the search time.

    [root@testvm1 system]# journalctl -S today -u myMonitor.service
    -- Logs begin at Mon 2020-06-08 07:47:20 EDT, end at Thu 2020-06-11 09:40:47 EDT. --
    Jun 11 09:12:09 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
    Jun 11 09:12:09 testvm1.both.org free[377966]:               total        used        free      shared  buff/cache   available
    Jun 11 09:12:09 testvm1.both.org free[377966]: Mem:       12635740      522868    11032860        8016     1080012    11821508
    Jun 11 09:12:09 testvm1.both.org free[377966]: Swap:       8388604           0     8388604
    Jun 11 09:12:09 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
    [root@testvm1 system]#

A task triggered by a service can be a single program, a group of programs, or a script written in a scripting language. Through in   myMonitor.service   In the unit file   [Service]   Another task can be added to the service if the following line is added at the end of the block:

    ExecStart=/usr/bin/lsblk

Start the service again and check the log check results. The results should look like this. You should see the result output of two commands in the log:

    Jun 11 15:42:18 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
    Jun 11 15:42:18 testvm1.both.org free[379961]:               total        used        free      shared  buff/cache   available
    Jun 11 15:42:18 testvm1.both.org free[379961]: Mem:       12635740      531788    11019540        8024     1084412    11812272
    Jun 11 15:42:18 testvm1.both.org free[379961]: Swap:       8388604           0     8388604
    Jun 11 15:42:18 testvm1.both.org lsblk[379962]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    Jun 11 15:42:18 testvm1.both.org lsblk[379962]: sda             8:0    0  120G  0 disk
    Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─sda1          8:1    0    4G  0 part /boot
    Jun 11 15:42:18 testvm1.both.org lsblk[379962]: └─sda2          8:2    0  116G  0 part
    Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-root 253:0    0    5G  0 lvm  /
    Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
    Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
    Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
    Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
    Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   └─VG01-home 253:5    0   10G  0 lvm  /home
    Jun 11 15:42:18 testvm1.both.org lsblk[379962]: sr0            11:0    1 1024M  0 rom
    Jun 11 15:42:18 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
    Jun 11 15:42:18 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.

Now you know that your service can work as expected  / etc/systemd/system   Create under directory   myMonitor.timer   Timer unit file, add the following code:

    # This timer unit is for testing
    # By David Both
    # Licensed under GPL V2
    #
    [Unit]
    Description=Logs some system statistics to the systemd journal
    Requires=myMonitor.service
    [Timer]
    Unit=myMonitor.service
    OnCalendar=*-*-* *:*:00
    [Install]
    WantedBy=timers.target

stay   myMonitor.timer   In file   OnCalendar   Time format, * - * - * *: *: 00, the timer should be triggered every minute to execute   myMonitor.service   Unit. I will explore further later in the article   OnCalendar   set up.

So far, observe the logging associated with the service when it is triggered by a timer. You can also track the timer, and the tracking service allows you to see the results in near real time. implement   journalctl   Bring it when you need it  - f   Options:

    [root@testvm1 system]# journalctl -S today -f -u myMonitor.service
    -- Logs begin at Mon 2020-06-08 07:47:20 EDT. --

Execute but do not enable the timer to see what happens after it has been running for some time:

    [root@testvm1 ~]# systemctl start myMonitor.service
    [root@testvm1 ~]#

One result is displayed immediately, and the next one is about a minute later. Observe the log for a few minutes to see if you find the same thing as me:

    [root@testvm1 system]# journalctl -S today -f -u myMonitor.service
    -- Logs begin at Mon 2020-06-08 07:47:20 EDT. --
    Jun 13 08:39:18 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
    Jun 13 08:39:18 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
    Jun 13 08:39:19 testvm1.both.org free[630566]:               total        used        free      shared  buff/cache   available
    Jun 13 08:39:19 testvm1.both.org free[630566]: Mem:       12635740      556604    10965516        8036     1113620    11785628
    Jun 13 08:39:19 testvm1.both.org free[630566]: Swap:       8388604           0     8388604
    Jun 13 08:39:18 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
    Jun 13 08:39:19 testvm1.both.org lsblk[630567]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    Jun 13 08:39:19 testvm1.both.org lsblk[630567]: sda             8:0    0  120G  0 disk
    Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─sda1          8:1    0    4G  0 part /boot
    Jun 13 08:39:19 testvm1.both.org lsblk[630567]: └─sda2          8:2    0  116G  0 part
    Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-root 253:0    0    5G  0 lvm  /
    Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
    Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
    Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
    Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
    Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   └─VG01-home 253:5    0   10G  0 lvm  /home
    Jun 13 08:39:19 testvm1.both.org lsblk[630567]: sr0            11:0    1 1024M  0 rom
    Jun 13 08:40:46 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
    Jun 13 08:40:46 testvm1.both.org free[630572]:               total        used        free      shared  buff/cache   available
    Jun 13 08:40:46 testvm1.both.org free[630572]: Mem:       12635740      555228    10966836        8036     1113676    11786996
    Jun 13 08:40:46 testvm1.both.org free[630572]: Swap:       8388604           0     8388604
    Jun 13 08:40:46 testvm1.both.org lsblk[630574]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    Jun 13 08:40:46 testvm1.both.org lsblk[630574]: sda             8:0    0  120G  0 disk
    Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─sda1          8:1    0    4G  0 part /boot
    Jun 13 08:40:46 testvm1.both.org lsblk[630574]: └─sda2          8:2    0  116G  0 part
    Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-root 253:0    0    5G  0 lvm  /
    Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
    Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
    Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
    Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
    Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   └─VG01-home 253:5    0   10G  0 lvm  /home
    Jun 13 08:40:46 testvm1.both.org lsblk[630574]: sr0            11:0    1 1024M  0 rom
    Jun 13 08:40:46 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
    Jun 13 08:40:46 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
    Jun 13 08:41:46 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
    Jun 13 08:41:46 testvm1.both.org free[630580]:               total        used        free      shared  buff/cache   available
    Jun 13 08:41:46 testvm1.both.org free[630580]: Mem:       12635740      553488    10968564        8036     1113688    11788744
    Jun 13 08:41:46 testvm1.both.org free[630580]: Swap:       8388604           0     8388604
    Jun 13 08:41:47 testvm1.both.org lsblk[630581]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    Jun 13 08:41:47 testvm1.both.org lsblk[630581]: sda             8:0    0  120G  0 disk
    Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─sda1          8:1    0    4G  0 part /boot
    Jun 13 08:41:47 testvm1.both.org lsblk[630581]: └─sda2          8:2    0  116G  0 part
    Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-root 253:0    0    5G  0 lvm  /
    Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]
    Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usr
    Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmp
    Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-var  253:4    0   20G  0 lvm  /var
    Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   └─VG01-home 253:5    0   10G  0 lvm  /home
    Jun 13 08:41:47 testvm1.both.org lsblk[630581]: sr0            11:0    1 1024M  0 rom
    Jun 13 08:41:47 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
    Jun 13 08:41:47 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.

Don't forget to check the status of timers and services.

You probably noticed at least two things in your diary. First, you don't need to do anything to make   myMonitor.service   In unit   ExecStart   Trigger generated   STDOUT   Store in the log. These are all part of the functions of running services with systemd. However, it does mean that you need to be careful about the scripts executed in the service unit and how much they can produce   STDOUT.

Second, the timer is not accurate at 00 seconds per minute, and even the time interval between each execution is not exactly one minute. This is a deliberate design, but you can change this behavior if necessary (if only it challenges the sensitivity of your system administrator).

The original intention of this design is to prevent multiple services from being triggered at exactly the same time. For example, you can use time formats such as Weekly and Daily. These shortcuts are defined to be executed at 00:00:00 on a certain day. When multiple timers are defined in this way, it is very likely that they will execute at the same time.

The SYSTEMd timer is deliberately designed to trigger at random fluctuating time points near the specified time to avoid triggering at the same time. They are triggered semi randomly in a time window, which starts at the preset trigger time and ends one minute after the preset time. according to   systemd.timer   This trigger time remains in a stable position relative to other defined timer units. You can see in the log entry that the timer is triggered immediately after starting, and then 46 or 47 seconds after each minute.

In most cases, this probability jitter timer is fine. When scheduling tasks like performing backups, they only need to run during off-duty hours, which is no problem. The system administrator can choose the determined start time to ensure that it does not conflict with other tasks, such as the typical cron job time of 01:05:00, but there are a wide range of time values to meet this. A minute level of randomness in the start time is often irrelevant.

However, for some tasks, accurate trigger time is a hard requirement. For such tasks, you can add   Timer   The following declaration is added to the block to specify a higher trigger time span accuracy (accurate to microseconds):

    AccuracySec=1us

The time span can be used to specify the required precision and to define the time span for repeated events or one-time events. It can identify the following units:

◈   usec,us,µs◈   msec,ms◈   seconds,second,sec,s◈   minutes,minute,min,m◈   hours,hour,hr,h◈   days,day,d◈   weeks,week,w◈   months, month, m (defined as 30.44 days)   years, year, y (defined as 365.25 days)

All  / usr/lib/systemd/system   The timers in specify a more relaxed time accuracy, because accurate time is not so important. Look at the time format of timers created by these systems:

    [root@testvm1 system]# grep Accur /usr/lib/systemd/system/*timer
    /usr/lib/systemd/system/fstrim.timer:AccuracySec=1h
    /usr/lib/systemd/system/logrotate.timer:AccuracySec=1h
    /usr/lib/systemd/system/logwatch.timer:AccuracySec=12h
    /usr/lib/systemd/system/mlocate-updatedb.timer:AccuracySec=24h
    /usr/lib/systemd/system/raid-check.timer:AccuracySec=24h
    /usr/lib/systemd/system/unbound-anchor.timer:AccuracySec=24h
    [root@testvm1 system]#

look down  / usr/lib/systemd/system   The complete contents of some timer unit files under the directory to see how they are built.

In this experiment, it is not necessary to activate this timer at startup, but the following command can set the startup self startup:

    [root@testvm1 system]# systemctl enable myMonitor.timer

The unit file you create does not need to be executable. You also don't need to enable the service because it is triggered by a timer. You can still manually trigger the service unit on the command line if you need it. Try it and watch the log.

For details on timer accuracy, event time specifications, and trigger events, see the man pages of systemd.timer and systemd.time.

Timer type

The systemd timer also has some functions that cannot be found in cron. cron is triggered only on a certain, repeated and specific date and time. The systemd timer can be configured to trigger when the state of other systemd units changes. For example, the timer can be configured to be triggered after the system is powered on, started, or a certain service unit is activated. These are called monotonic timers. "Monotone" refers to a continuously growing counter or sequence. These timers are not persistent because they reset after each start.

Table 1 lists some monotonic timers and a short definition of each timer, with   OnCalendar   Timers, which are not monotonic, are used to specify a certain time that may be repeated in the future. This information comes from   systemd.timer   There are some unimportant modifications to the manual page of.

timerMonotonicitydefinition
OnActiveSec= X Defines a timer related to the moment when the timer is activated.
OnBootSec= X Defines a timer related to the machine start time.
OnStartupSec= X Defines a timer associated with the first start of the service manager. For the system timer, this timer and   OnBootSec=   Similarly, because the system service manager starts a short time after the machine starts. It is particularly useful when configured as a unit running in each user service manager, because the user's service manager usually starts after the first login, not after the machine starts.
OnUnitActiveSec= X Defines a timer related to the last activation time of the timer to be activated.
OnUnitInactiveSec= X Defines a timer related to the last deactivation time of the timer to be activated.
OnCalendar=   A real-time (real-time clock) timer with date event expression syntax is defined. see   systemd.time(7)   For more syntax information related to calendar event expressions. In addition, its semantics and   OnActiveSec=   similar.

Monotone timers can use the same short name as their time span, which we mentioned earlier   AccuracySec   Expression, but systemd converts these names into seconds. For example, you want to set a timer to trigger an event five days after the system starts; It may look like   OnBootSec=5d. If the machine starts on   At 09:45:27, June 15, 2020, the timer will   2020-06-20 09:45:27   Or within one minute after that.

Calendar event format

Calendar event format is the key to trigger the timer at the required repetition time. Let's start looking at some   OnCalendar   Format for use with.

Compared with the format in crontab, systemd and its timers use different time and calendar format styles. It is more flexible than crontab and can use similar tools   at   Command mode allows fuzzy dates and times. It should also be familiar enough to make it easy to understand.

systemd timer usage   OnCalendar=   The basic format is   DOW YYYY-MM-DD HH:MM:SS. Dow (day of the week) is optional. Other fields can match any value of this position with an asterisk (*). All calendar time formats will be converted to standard format. If the time is not specified, it is set to   00:00:00. If the date is not specified but the time is specified, the next matching time may be today or tomorrow, depending on the current time. Months and weeks can use names or numbers. Each cell can use a comma separated list. The cell range can be used between the start value and the end value  ..  appoint.

There are some interesting options for specifying a date. The tilde (~) can specify the last day of the month or a few days before the last day/   Can be used to specify the day of the week as a modifier.

How many are here   OnCalendar   Examples of typical time formats used in expressions.

Date event formatdescribe
DOW YYYY-MM-DD HH:MM:SS  
*-*-* 00:15:30 0:15:30 every month every year
Weekly 00:00:00 every Monday
Mon *-*-* 00:00:00 ditto
Mon ditto
Wed 2020-*-* 00:00:00 every Wednesday in 2020
Mon..Fri 2021-*-* 00:00:00 on every working day (Monday to Friday) in 2021
2022-6,7,8-1,15 01:15:00 01:15:00 from June 1 to August 15, 2022
Mon *-05~03 The next Monday in May is also the penultimate day at the end of the month
Mon..Fri *-08~04 The penultimate day of the end of August in any year must also be a working day
*-05~03/2 The penultimate day at the end of May, and then again in two days. Repeat once a year. Notice that this expression uses the tilde (~).
*-05-03/2 The third day of May, and then repeat every two days until the end of May. Notice that this expression uses a dash (-).

Test calendar format

systemd provides an excellent tool for detecting and testing the format of calendar time events in timers. systemd-analyze calendar   The tool parses a time event format and provides standard format and other interesting information, such as the date and time of the next "pass" (i.e. match), and the approximate time before the next trigger.

First, look at the future days without time (Note:   Next elapse   and   UTC   The time of will change according to your local time zone):

    [student@studentvm1 ~]$ systemd-analyze calendar 2030-06-17
      Original form: 2030-06-17                
    Normalized form: 2030-06-17 00:00:00        
        Next elapse: Mon 2030-06-17 00:00:00 EDT
           (in UTC): Mon 2030-06-17 04:00:00 UTC
           From now: 10 years 0 months left    
    [root@testvm1 system]#

Now add a time. In this example, the date and time are parsed separately as irrelevant parts:

    [root@testvm1 system]# systemd-analyze calendar 2030-06-17 15:21:16
      Original form: 2030-06-17                
    Normalized form: 2030-06-17 00:00:00        
        Next elapse: Mon 2030-06-17 00:00:00 EDT
           (in UTC): Mon 2030-06-17 04:00:00 UTC
           From now: 10 years 0 months left    
      Original form: 15:21:16                  
    Normalized form: *-*-* 15:21:16            
        Next elapse: Mon 2020-06-15 15:21:16 EDT
           (in UTC): Mon 2020-06-15 19:21:16 UTC
           From now: 3h 55min left              
    [root@testvm1 system]#

In order to analyze the date and time as a unit, you can wrap them in quotation marks. You're in the timer unit   OnCalendar=   Remember to remove the quotation marks when using the time format, otherwise an error will be reported:

    [root@testvm1 system]# systemd-analyze calendar "2030-06-17 15:21:16"
    Normalized form: 2030-06-17 15:21:16        
        Next elapse: Mon 2030-06-17 15:21:16 EDT
           (in UTC): Mon 2030-06-17 19:21:16 UTC
           From now: 10 years 0 months left    
    [root@testvm1 system]#

Now let's test the example in Table 2. I especially like the last one:

    [root@testvm1 system]# systemd-analyze calendar "2022-6,7,8-1,15 01:15:00"
      Original form: 2022-6,7,8-1,15 01:15:00
    Normalized form: 2022-06,07,08-01,15 01:15:00
        Next elapse: Wed 2022-06-01 01:15:00 EDT
           (in UTC): Wed 2022-06-01 05:15:00 UTC
           From now: 1 years 11 months left
    [root@testvm1 system]#

Let's look at an example in which we list five elapsed times of the time expression.

    [root@testvm1 ~]# systemd-analyze calendar --iterations=5 "Mon *-05~3"
      Original form: Mon *-05~3                
    Normalized form: Mon *-05~03 00:00:00      
        Next elapse: Mon 2023-05-29 00:00:00 EDT
           (in UTC): Mon 2023-05-29 04:00:00 UTC
           From now: 2 years 11 months left    
           Iter. #2: Mon 2028-05-29 00:00:00 EDT
           (in UTC): Mon 2028-05-29 04:00:00 UTC
           From now: 7 years 11 months left    
           Iter. #3: Mon 2034-05-29 00:00:00 EDT
           (in UTC): Mon 2034-05-29 04:00:00 UTC
           From now: 13 years 11 months left    
           Iter. #4: Mon 2045-05-29 00:00:00 EDT
           (in UTC): Mon 2045-05-29 04:00:00 UTC
           From now: 24 years 11 months left    
           Iter. #5: Mon 2051-05-29 00:00:00 EDT
           (in UTC): Mon 2051-05-29 04:00:00 UTC
           From now: 30 years 11 months left    
    [root@testvm1 ~]#

This should provide you with enough information to start testing your   OnCalendar   Time format. systemd-analyze   Tools can be used for other interesting analyses, which I will explore in the next article in this series.

summary

The systemd timer can be used to perform the same tasks as the cron tool, but provides more flexibility by triggering events in calendar and monotonic time formats.

Although the service unit you created for this experiment is usually called by a timer, you can use it at any time   systemctl start myMonitor.service   Command to trigger it. You can script multiple maintenance tasks in one timer; They can be Bash scripts or other Linux programs. You can run the service by triggering a timer to run all the scripts, or you can execute separate scripts as needed.

I will explore the usefulness of systemd time format in more depth in the next article.

I haven't seen any sign that cron and at will be abandoned. I hope this will not happen, because at least   at   It is much easier to execute a one-time scheduling task than the system D timer.

reference material

There are a lot of references about systemd on the Internet, but most of them are a little brief, obscure and even misleading. In addition to the materials mentioned in this article, the following pages provide reliable and detailed introduction to systemd.

◈   Fedora project has a practical and easy-to-use article   Getting started with systemd , it contains almost all the information you need to know about how to use systemd to configure, manage and maintain Fedora computers. ◈   Fedora project also has a good prospect   memorandum , cross reference the past SystemV command and systemd command for comparison. ◈   For the technical details of systemd and the reasons for creating this project, please check   Freedesktop.org   Upper   systemd description. ◈ Linux.com   The "more system D fun" column of provides more advanced system D   Information and skills.

In addition, there are a series of in-depth technical articles written by Lennart poetering, the designer and main implementer of systemd, for Linux system administrators. These articles were written between April 2010 and September 2011, but they are as relevant now as they were then. Many other good articles on systemd and its ecology are based on these articles:

◈ Rethinking PID 1◈ systemd for Administrators,Part I◈ systemd for Administrators,Part II◈ systemd for Administrators,Part III◈ systemd for Administrators,Part IV◈ systemd for Administrators,Part V◈ systemd for Administrators,Part VI◈ systemd for Administrators,Part VII◈ systemd for Administrators,Part VIII◈ systemd for Administrators,Part IX◈ systemd for Administrators,Part X◈ systemd for Administrators,Part XI

via: https://opensource.com/article/20/7/systemd-timers

Reprinted from: https://mp.weixin.qq.com/s/HpDVp1sNYve8b7OdoHdGNw

Tags: Linux

Posted on Mon, 29 Nov 2021 02:53:16 -0500 by iambradn