I want to distinguish between systemd unit run by systemd timer or invoked manually with systemctl. I.e. to check, if backup is triggered as periodical job by schedule or is done "on demand".

What I've found so far:

  • there is no place for setting environment variables in timer units ?)
  • environment passed to unit is the same, regardless if it is triggered by the timer or manually

Running both periodic and manual invocations through systemd seems to be more convenient than putting note in MOTD "For scheduled operations systemd timers are used, for manual jobs use scripts in /usr/local/bin" ;)

Do you have any ideas (other than unit instantiation and copying unit with different environment for manual use )?

  • systemd.timer triggers a systemd.service unit, so you can use the Environment directive in the service file. Or install the systemd-cron package, to emulate the good old crontab. – ingopingo Feb 8 '18 at 16:03
  • Yes, at the moment I've found two resolutions: 1: copy systemd unit and set environment variables (so one more unit to maintain/remember about and invoke different unit for manual and scheduled operation) or 2: use "good old cron", where I can modify environment or just use additional parameter in command line. So "Great shining systemd" vs. "Good Old Unix KISS" once again - "at least I tried" ;) – Wheart Feb 8 '18 at 22:21

but here is a simple way to pass argument from your timer to your unit, and that is use templates


create a service with @ i the name




   ExecStart=/bin/echo 'hello from %i'

then your timer can be something like


Description=timer for me



you see that now whatever you pass after the @ will become %i in your service file. so now you just

[~] sudo systemctl daemon-reload 
[~] sudo systemctl start me.timer
[~] sudo systemctl status me@timer.service
● me@timer.service - test
   Loaded: loaded (/etc/systemd/system/me@.service; static; vendor preset: enabled)
   Active: active (running) since Thu 2018-02-08 19:35:38 PST; 7ms ago
 Main PID: 8899 (echo)
    Tasks: 1 (limit: 4915)
   CGroup: /system.slice/system-me.slice/me@timer.service

Feb 08 19:35:38 algx systemd[1]: Started test.
Feb 08 19:35:38 algx echo[8899]: hello from timer

if you want to start the unit from the cli, just give it another param after the @

[~] sudo systemctl start me@cli
[~] sudo systemctl status me@cli.service
✘  ~  sudo systemctl status me@cli.service
● me@cli.service - test
   Loaded: loaded (/etc/systemd/system/me@.service; static; vendor preset: enabled)
   Active: inactive (dead)

Feb 08 19:32:48 algx systemd[1]: Started test.
Feb 08 19:32:48 algx echo[8490]: hello from cli

this way you have a clear distinction on what is timer and what is cli, but you can expand this to any type of trigger... you dont maintain 2 units files, but you have a clear separation because from the point of view of systemd this are 2 different services.

| improve this answer | |
  • It is exactly what I mean writing about "unit instantiation" - and it is already used to distinguish between multiple instances of service (choosing right environment file). Is it possible to parse %i inside unit file (i. ie. having units me@instance1-cli.service and me@instance1-timer.service pass to the further processing just "instance1")? – Wheart Feb 9 '18 at 8:58
  • sadly no, that is up to you app, there is more info in freedesktop.org/software/systemd/man/systemd.unit.html but in a nutshell, the thing after the @ is called the instance name, and its just one thing. – aleivag Feb 9 '18 at 15:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.