Systemd/timers: Difference between revisions
imported>Onny mNo edit summary  | 
				 Added `RemainAfterExit = true;` to the example since this is probably what people want.  | 
				||
| (14 intermediate revisions by 11 users not shown) | |||
| Line 1: | Line 1: | ||
{{Systemd/breadcrumb}}  | |||
==   | <translate>  | ||
<!--T:1-->  | |||
Timers are systemd unit files whose name ends in .timer that control .service files or events. Timers can be used as an alternative to <code>cron</code>. Timers have built-in support for calendar-based events and monotonic time events, and can be run asynchronously.  | |||
</translate>  | |||
<  | <translate>  | ||
== Configuration == <!--T:2-->  | |||
</translate>  | |||
<translate>  | |||
<!--T:3-->  | |||
The following example timer runs a systemd unit every 5 minutes which invokes a bash script.  | |||
</translate>  | |||
<syntaxhighlight lang="nix">  | |||
systemd.timers."hello-world" = {  | systemd.timers."hello-world" = {  | ||
   wantedBy = [ "timers.target" ];  |    wantedBy = [ "timers.target" ];  | ||
| Line 11: | Line 18: | ||
       OnBootSec = "5m";  |        OnBootSec = "5m";  | ||
       OnUnitActiveSec = "5m";  |        OnUnitActiveSec = "5m";  | ||
      # Alternatively, if you prefer to specify an exact timestamp  | |||
      # like one does in cron, you can use the `OnCalendar` option  | |||
      # to specify a calendar event expression.  | |||
      # Run every Monday at 10:00 AM in the Asia/Kolkata timezone.  | |||
      #OnCalendar = "Mon *-*-* 10:00:00 Asia/Kolkata";  | |||
       Unit = "hello-world.service";  |        Unit = "hello-world.service";  | ||
     };  |      };  | ||
| Line 22: | Line 34: | ||
   serviceConfig = {  |    serviceConfig = {  | ||
     Type = "oneshot";  |      Type = "oneshot";  | ||
     User= "  |      User = "root";  | ||
    RemainAfterExit = true; # Prevents the service from automatically starting on rebuild. See https://discourse.nixos.org/t/how-to-prevent-custom-systemd-service-from-restarting-on-nixos-rebuild-switch/43431  | |||
  };  | |||
};  | |||
</syntaxhighlight>  | |||
Alternatively here, avoid quotes when calling for the binary and its command options:   | |||
<syntaxHighlight lang="nix">  | |||
${pkgs.foo}/bin/foo command-options   | |||
</syntaxHighlight>  | |||
This will yield the same result as running   | |||
<syntaxhighlight lang="bash">  | |||
foo command-options  | |||
</syntaxhighlight>  | |||
in your terminal.  | |||
==== Verifying your timestamp for systemd.time ====  | |||
If you do not understand the format that [https://www.freedesktop.org/software/systemd/man/latest/systemd.time.html systemd.time] expects, you can use the <code>systemd-analyze</code>'s <code>calendar</code> sub-command to understand the next ''N'' times when the timer will get triggered. Following is an example:<syntaxhighlight lang="shell-session">  | |||
$ systemd-analyze calendar --iterations=5 "10:00:00"  | |||
  Original form: 10:00:00  | |||
Normalized form: *-*-* 10:00:00  | |||
    Next elapse: Sat 2024-12-07 10:00:00 IST  | |||
       (in UTC): Sat 2024-12-07 04:30:00 UTC  | |||
       From now: 33min left  | |||
   Iteration #2: Sun 2024-12-08 10:00:00 IST  | |||
       (in UTC): Sun 2024-12-08 04:30:00 UTC  | |||
       From now: 24h left  | |||
   Iteration #3: Mon 2024-12-09 10:00:00 IST  | |||
       (in UTC): Mon 2024-12-09 04:30:00 UTC  | |||
       From now: 2 days left  | |||
   Iteration #4: Tue 2024-12-10 10:00:00 IST  | |||
       (in UTC): Tue 2024-12-10 04:30:00 UTC  | |||
       From now: 3 days left  | |||
   Iteration #5: Wed 2024-12-11 10:00:00 IST  | |||
       (in UTC): Wed 2024-12-11 04:30:00 UTC  | |||
       From now: 4 days left  | |||
</syntaxhighlight>  | |||
====Using the <code>systemd.services.<name>.startAt</code> shorthand====  | |||
If you only want a service to execute at an interval and don't plan to configure the timer much more, you can use the <code>systemd.services.<name>.startAt</code> option. This will have the underlying systemd module in nixpkgs create the timer for you, and set its <code>OnCalendar</code> field. Note that the semantics for <code>OnCalendar</code> are different to <code>OnUnitActiveSec</code>.  | |||
This example shows the previous <code>hello-world</code> service configured with <code>startAt</code>, running every 5 minutes.  | |||
<syntaxHighlight lang="nix">  | |||
systemd.services."hello-world" = {  | |||
  script = ''  | |||
    set -eu  | |||
    ${pkgs.coreutils}/bin/echo "Hello World"  | |||
  '';  | |||
  serviceConfig = {  | |||
    Type = "oneshot";  | |||
    User = "root";  | |||
  };  | |||
  startAt = "*:0/5";  | |||
};  | |||
</syntaxHighlight>  | |||
====Running timer on a schedule====  | |||
<translate>  | |||
<!--T:4-->  | |||
The following example starts once a day (at 12:00am). When activated, it triggers the service immediately if it missed the last start time (option Persistent=true), for example due to the system being powered off.  | |||
</translate>  | |||
<syntaxHighlight lang="nix">  | |||
...  | |||
  timerConfig = {  | |||
      OnCalendar = "daily";  | |||
      Persistent = true;    | |||
   };  |    };  | ||
};  | };  | ||
</syntaxHighlight>  | </syntaxHighlight>  | ||
<translate>  | |||
<!--T:5-->  | |||
More examples can be found at the [https://wiki.archlinux.org/title/Systemd/Timers Arch Wiki] and at the <code>systemd.timer</code> manpage.  | |||
</translate>  | |||
<translate>  | |||
== Usage == <!--T:6-->  | |||
</translate>  | |||
<translate>  | |||
<!--T:7-->  | |||
List active timers and their current state:  | |||
</translate>  | |||
<syntaxhighlight lang="bash">  | |||
systemctl list-timers  | |||
</syntaxhighlight>  | |||
<translate>  | |||
<!--T:8-->  | |||
Manually run a service once for testing purposes:  | |||
</translate>  | |||
<syntaxhighlight lang="bash">  | |||
systemctl start hello-world  | |||
</syntaxhighlight>  | |||
[[Category:systemd]]  | |||