Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have an Arch Linux system with systemd and I've created my own service. The configuration service at /etc/systemd/system/myservice.service looks like this:

Description=My Daemon



Now I want to have an environment variable set for the /bin/myforegroundcmd. How do I do that?

share|improve this question
up vote 43 down vote accepted

Times change and so do best practices.

The current best way to do this is:

Create a directory /etc/systemd/system/myservice.service.d, and inside that directory create a file whose name ends in .conf, and in this file you can add to or override any part of the unit shipped by the distribution.

For instance, in a file /etc/systemd/system/myservice.service.d/myenv.conf:


Also note that if the directory exists and is empty, your service will be disabled! If you don't intend to put something in the directory, ensure that it does not exist.

For reference, the old way was:

The recommended way to do this is to create a file /etc/sysconfig/myservice which contains your variables, and then load them with EnvironmentFile.

For complete details, see Fedora's documentation on how to write a systemd script.

share|improve this answer
I guess the sysconfig path is specific to Fedora but the question is about Arch Linux. The answer by paluh is more interesting I think – Ludovic Kuty Apr 27 '13 at 8:49
@LudovicKuty systemd is virtually identical across distributions that use it. – Michael Hampton Dec 16 '13 at 4:36
Good to know :) – Ludovic Kuty Dec 16 '13 at 12:53
/etc/sysconfig is Fedora-specific. AFAIR Arch Linux was pushing for having the config files somewhere package-specific rather in /etc rather than that Fedora-specific location. Like /etc/myservice.conf, though using extra file doesn't seem the right way here. – Michał Górny Apr 23 '14 at 7:13
No, no, no. /etc/sysconfig is not recomended. It is discouraged, along with /etc/default/* from debian, because they are pointless, and the names are meaningless and make sense only for backwards compatibility reasons (all of /etc is about configuration of the system, not just /etc/sysconfig, and /etc/defaults is for overrides, not the defaults). Just put the definitions directly in the unit file, or if it is not possible, in an enviornment file that has a package specific location (like Michał's comment suggests). – zbyszek Oct 4 '14 at 18:41

The answer depends on whether the variable is supposed to be constant (that is, not supposed to be modified by user getting the unit) or variable (supposed to be set by the user).

Since it's your local unit, the boundary is quite blurry and either way would work. However, if you started to distribute it and it would end up in /usr/lib/systemd/system, this would become important.

Constant value

If the value doesn't need to change per instance, the preferred way would be to place it as Environment=, directly in the unit file:

Description=My Daemon

Environment="FOO=bar baz"


The advantage of that is that the variable is kept in a single file with the unit. Therefore, the unit file is easier to move between systems.

Variable value

However, the above solution doesn't work well when sysadmin is supposed to change the value of the environment variable locally. More specifically, the new value would need to be set every time the unit file is updated.

For this case, an extra file is to be used. How — usually depends on the distribution policy.

One particularly interesting solution is to use /etc/systemd/system/myservice.service.d directory. Unlike other solutions, this directory is supported by systemd itself and therefore comes with no distribution-specific paths.

In this case, you place a file like /etc/systemd/system/myservice.service.d/local.conf that adds the missing parts of unit file:

Environment="FOO=bar baz"

Afterwards, systemd merges the two files when starting the service (remember to systemd daemon-reload after changing either of them). And since this path is used directly by systemd, you don't use EnvironmentFile= for this.

If the value is supposed to be changed only on some of the affected systems, you may combine both solutions, providing a default directly in the unit and a local override in the other file.

share|improve this answer - you have two options (one already pointed by Michael):



share|improve this answer

Michael gave one clean solution but I wanted to get updated env variable from script. Unfortunately executing bash commands is not possible in systemd unit file. Fortunately you can trigger bash inside ExecStart:

Note that this setting does not directly support shell command lines. If shell command lines are to be used they need to be passed explicitly to a shell implementation of some kind.

Example in our case is then:

ExecStart=/bin/bash -c "ENV=`script`; /bin/myforegroundcmd"
share|improve this answer
This won't work for multiple reasons (unless it's a "one-shot" service, which is rather pointless). I managed to get the following to work: /bin/bash -a -c 'source /etc/sysconfig/whatever && exec whatever-program' . The -a ensures the environment is exported to the sub-process (unless you want to prefix all variables in whatever with export ) – Otheus Apr 29 '15 at 22:42
why it won't work? It should always trigger entire command which includes executing the script, ain't it? – user1830432 Apr 30 '15 at 8:29
Maybe ExecStart=/usr/bin/env ENV=script /bin/myforegroundcmd is a little better solution in this case. – kstep Nov 26 '15 at 6:18
@Otheus: Great answer, saved by day when I had to create a Tomcat 8 Unit file. – Daniel Apr 13 at 6:58

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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