Is it possible to give my systemd service more than one argument?

I'd like to execute a program with multiple arguments which have to be decided by the final user.

E.g: ./program arg1 arg2

To start it a single argument app I'd need something like systemctl start arg1@program, where in the service definition I have ExecStart = /usr/bin/program ℅i.


  • 1
    Sounds like what you want is a config file.
    – Daniel B
    Mar 14, 2014 at 10:27
  • I need to change it on the go. Do I strictly need a conf file?
    – peperunas
    Mar 14, 2014 at 10:33
  • @peperunas you don't need a conf file, see my answer which works without any extra files
    – nonagon
    Jan 4, 2018 at 16:23

4 Answers 4


Yes you can! Define them in a file somewhere and add them to EnvironmentFile in your systemd Service. For example, say the contents of /etc/.progconf are:


And your .service file:

ExecStart = /usr/bin/prog $ARG1 $ARG2

You can write to that file if you need to change them on the go. A service shouldn't change its options very often, maybe consider autostarting or cron if you need to achieve that.

For more examples check: https://wiki.archlinux.org/index.php/Systemd/Services

  • Heh, quite handy, didn't think of that. I have to agree though: Service parameters don't change on a regular basis, and neither do their config files.
    – Daniel B
    Mar 14, 2014 at 11:55
  • if the service file uses environment variables, can you say VAR1=... VAR2=... systemctl start foobar.service to pass the variables? Jun 10, 2015 at 18:16
  • Yes, I believe you can
    – alexm
    Jun 11, 2015 at 11:31
  • 7
    @JohannesSchaub-litb, no, you can't. There is a PassEnvironment directive, but it takes variables from the systemd process (normally PID 1), not from systemctl. Environment variables from the systemctl process don't get propagated to the service being started.
    – cjm
    Mar 31, 2016 at 19:55
  • 2
    But upstart can run multiple instances of the same service, with different parameters. For example a mail server on eth0 and another instance of said mailserver on eth1, passing the parameter to upstart and managing them as separate services. Can systemd do this?
    – LtWorf
    Jan 26, 2017 at 10:03

I wanted to do the same thing, but without a separate file for each combination of arguments. I found that I could pass one long argument with spaces and then use systemd's environment variable space-splitting feature to separate the arguments.

I made a service with filename argtest@.service (note the trailing 'at sign' which is required when a service takes arguments).

Description=Test passing multiple arguments

ExecStart=/tmp/test.py $SCRIPT_ARGS

I run this with sudo systemctl start argtest@"arg1 arg2 arg3".service and it passes arg1, arg2 and arg3 as separate command-line arguments to test.py.

  • "note the trailing ampersand": I find no ampersand in your reply. Can you edit your reply to be clearer on this point? Apr 4, 2018 at 23:12
  • Yes, sorry about that!
    – nonagon
    Apr 5, 2018 at 2:20
  • I think the @ is only needed when you use the %I as you do. It's an instance of the service.
    – Toby
    Apr 9, 2018 at 12:21
  • Agreed, I just ran into a few blog posts which omitted it. I'll clarify in my answer.
    – nonagon
    Apr 9, 2018 at 15:31
  • 3
    On my debian I get Invalid unit name "argtest@arg1 arg2.service" was escaped as "argtest@arg1\x20arg2.service" (maybe you should use systemd-escape?)
    – sgargel
    Nov 29, 2021 at 9:35

Easiest I have found is:

ExecStart=/bin/bash -c "\"/path/with spaces/to/app\" arg1 arg2 arg3 \"arg with space\""

Keeps it all self contained.

Having said that, I have found that at least on Ubuntu 18.04 LTS, I don't even need to do that, I can do this and it works fine:

ExecStart="/path/with spaces/to/app" arg1 arg2 arg3 "arg with space"

$vars work as arguments with this pattern as well.


Tell your users to override the service by creating a drop-in snippet through the use of the edit option in systemctl.

Firstly, start with some sane defaults. Let's assume the ExecStart part of your service declares the following:

ExecStart=./program arg1

Now any user of this service can decide that they want to use a different set of arguments for running the program. They can do that by creating a drop-in snippet with:

systemctl edit myservice.service

In the new file, they simply write the following to override the ExecStart:

ExecStart=./program arg1 arg2

The benefit of doing it this way is that the end result does not involve modifying the system-installed service which may conflict with some package managers.

And that's it!

Now just reload systemd (systemctl daemon-reload) and restart the service (systemctl restart myservice.service).

When the service restarts, it will always also load the user's modifications.

I hope that helps


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.