103

Is it possible to create service with the same script started with different input parameters?

Example:

[Unit]
Description=script description

[Service]
Type=simple
ExecStart=/script.py parameters1
ExecStart=/script.py parameters2
Restart=on-failure

[Install]
WantedBy=multi-user.target

Is it possible?

Will it be launched in serial-mode? Or in two different process?

3
  • 10
    Why in the world was this closed? The question obviously involves a specific problem and software tools used primarily by programmers. Dec 28, 2022 at 22:31
  • @aquirdturtle I think they want it to be posted to superusers or U&L.... but realistically probably just an aggressive mod
    – ridderhoff
    Feb 16 at 21:27
  • Seeing how this question has so many upvotes and is in the top of the google results it should really be reopened. Additionally it's really dumb that questions can't be moved to the proper forum! Anyhow! The proper way to do this is simply by using ; to separate the commands in ExecStart. They will then be executed sequentially. The docs: freedesktop.org/software/systemd/man/latest/…
    – andsens
    5 hours ago

2 Answers 2

154

if Type=simple in your unit file, you can only specify one ExecStart, but you can add as many ExecStartPre, ExecStartPost, but none of this is suited for long running commands, because they are executed serially and everything one start is killed before starting the next one.

If Type=oneshot you can specify multiple ExecStart, they run serially not in parallel.

If what you want is to run multiple units in parallel, there a few things you can do:

If they differ on 1 param

You can use template units, so you create a /etc/systemd/system/[email protected]. NOTE: (the @ is important).

[Unit]
Description=script description %I

[Service]
Type=simple
ExecStart=/script.py %i
Restart=on-failure

[Install]
WantedBy=multi-user.target

And then you exec:

$ systemctl start [email protected] [email protected]

or...

Target dependencies

You can create multiple units that links to a single target:

#/etc/systemd/system/bar.target
[Unit]
Description=bar target
Requires=multi-user.target
After=multi-user.target
AllowIsolate=yes

And then you just modify you .service units to be WantedBy=bar.target like:

#/etc/systemd/system/[email protected]
[Unit]
Description=script description %I

[Service]
Type=simple
ExecStart=/script.py %i
Restart=on-failure

[Install]
WantedBy=bar.target

Then you just enable the foo services you want in parallel, and start the bar target like this:

$ systemctl daemon-reload
$ systemctl enable [email protected]
$ systemctl enable [email protected]
$ systemctl start bar.target

NOTE: that this works with any type of units not only template units.

8
  • 2
    Very nice solution! But note that systemctl stop bar.target doesn't stop any of these linked services :'(
    – jirislav
    Oct 26, 2018 at 23:09
  • @aleivag what about if I want stop all the running services? should I execute systemctl stop foo@param_number.service for each service? and if I have 100 services registered to the same target?
    – Spartaok
    Nov 20, 2018 at 11:45
  • 1
    @Spartaok you do systemctl stop foo@*
    – aleivag
    Dec 6, 2018 at 21:15
  • 6
    Also you may add PartOf=bar.target into [Unit] section of [email protected]. This allows to stop services when target is being stopped.
    – Johny
    Dec 24, 2018 at 15:49
  • 4
    Pay attention that if you want bar.target started during system boot you need to add [Install] section with WantedBy=multi-user.target line into bar.target and enable this target with the next command: systemctl enable bar.target
    – Johny
    Dec 24, 2018 at 15:51
35

You can use ExecStartPre or ExecStartPost for one of scripts

[Unit]
Description=script description

[Service]
Type=simple
ExecStartPre=/script.py parameters1
ExecStart=/script.py parameters2
Restart=on-failure

[Install]
WantedBy=multi-user.target
2
  • 3
    But in the control I read " Additional commands that are executed before or after the command in ExecStart=, respectively. Syntax is the same as for ExecStart=, except that multiple command lines are allowed and the commands are executed one after the other, serially " In your case, i should wait that the first script on success before the system start second script or not? Thank you
    – Riccardo
    Jan 11, 2018 at 9:05
  • Yes, in this solution you should wait for success of first script. Another solution is about creating bash script that get parameters1 and parameters2 and then pass them to python scripts. Jan 12, 2018 at 20:43

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