You are not logged in.

#1 2020-11-01 05:21:20

MountainX
Member
Registered: 2016-02-08
Posts: 371

using environment variables in script run by systemd unit

I have a bash script that is executed by a systemd timer unit. My bash script needs to reference a variable defined in /etc/bash.bashrc. What is the best way to do this?

One option I read was:

Creating the "/etc/systemd/system.conf.d/10-default-env.conf" file will set default environment variables for all systemd units.

I read it should contain one key=value pair per line. If I use this approach, I have two questions:

1. do I have to reboot in order for systemd to source my variables defined in "/etc/systemd/system.conf.d/10-default-env.conf"? Either I do have to reboot (which I cannot do right now) or I have done something wrong.

2. is there a way to use the variable(s) already defined (and exported) in /etc/bash.bashrc? I want to  avoid having same variable defined in two different places.

One of the pages I've been reading is: https://unix.stackexchange.com/a/455283/15010

I see a few ways to do this, but they all seem to require that I define the already defined variable in another file.

Last edited by MountainX (2020-11-01 05:28:44)

Offline

#2 2020-11-01 16:10:41

twelveeighty
Member
Registered: 2011-09-04
Posts: 1,456

Re: using environment variables in script run by systemd unit

Have you actually *tried* setting the value in 10-default-env.conf (without rebooting) to see if it works?

Offline

#3 2020-11-01 17:25:49

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,516
Website

Re: using environment variables in script run by systemd unit

MountainX wrote:

2. is there a way to use the variable(s) already defined (and exported) in /etc/bash.bashrc?

Only if you source the bash.bashrc in your script.  But if you want this variable to be accessible by more than interactive shells, then bash.bashrc is the wrong place for it.  I'd agree it should only be defined in one location, but put it in one correct location.  What is the variable used for?

Last edited by Trilby (2020-11-01 20:26:03)


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#4 2020-11-01 19:05:07

snakeroot
Member
Registered: 2012-10-06
Posts: 177

Re: using environment variables in script run by systemd unit

@Trilby, in lieu of sourcing the /etc/bash.bashrc, which would bring the whole of the bash.bashrc file with it, couldn't you include in something like:

SCRIPT_VARIABLE=$(sed -nE 's/^BASHRC_VARIABLE=//p' /etc/bash.bashrc)

instead?

Offline

#5 2020-11-01 20:25:35

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,516
Website

Re: using environment variables in script run by systemd unit

In some cases, perhaps.  If one knows ahead of time that it is currently and will remain forever a safe assumption that the variable is defined on one line in the bashrc with no reliance on anything that came before it and no line parsing required on it.  But even if that assumption was valid, that'd not be a sane way to handle this.

Really, don't do something incorrectly in one place only to have to need ugly fragile hacks to deal with it in other places.  Just do it properly the first time.

Last edited by Trilby (2020-11-01 20:26:56)


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#6 2020-11-01 20:27:06

MountainX
Member
Registered: 2016-02-08
Posts: 371

Re: using environment variables in script run by systemd unit

Trilby wrote:
MountainX wrote:

2. is there a way to use the variable(s) already defined (and exported) in /etc/bash.bashrc?

Only if your source the bash.bashrc in your script.  But if you want this variable to be accessible by more than interactive shells, then bash.bashrc is the wrong place for it.  I'd agree it should only be defined in one location, but put it in one correct location.  What is the variable used for?

I got the person on our team who originally put the variable definition into /etc/bash.bashrc to agree to move it out into a file that is sourced by /etc/bash.bashrc, so now I can source that file too.

Have you actually *tried* setting the value in 10-default-env.conf (without rebooting) to see if it works?

Yes, I did try that before I asked the question. Unless anyone says otherwise, I will have to assume setting a value in 10-default-env.conf requires a reboot before that value is available system-wide.

A workaround (not a good one) was to define 10-default-env.conf as an EnvironmentFile in my systemd unit file. That worked without a reboot, but it would be stupid to keep that definition in the unit file.

Offline

#7 2020-11-01 20:35:43

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,516
Website

Re: using environment variables in script run by systemd unit

You've still not said what the variable is for or what the desired scope actually is - so I don't know if this will be useful, but in most cases I could think of for something like this, I'd put a file in /etc/profile.d/ defining the variable(s) needed for this tool / service / whatever.  This is sourced for login shells, and can be specified as an EnvironmentFile for the systemd service.

Again, even sourcing this from bashrc seems odd for something you want to use so broadly.  Bashrc is for interactive shell sessions.

Note there's also "systemctl set-environment" or "systemctl import-environment" (optionally with the --user flag) which may be useful depending on what the use actually is.

These two approaches might also be combined with a /etc/profile.d/ file like the following (this probably only makes sense for user services which would require the --user flag added to systemctl; but then if the variable is being set for use in interactive user shells, this probably should be a user service!):

FOO=myvariablecontent
systemctl import-environment FOO

Last edited by Trilby (2020-11-01 20:44:18)


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#8 2020-11-01 20:47:50

MountainX
Member
Registered: 2016-02-08
Posts: 371

Re: using environment variables in script run by systemd unit

Trilby wrote:

You've still not said what the variable is for or what the desired scope actually is - so I don't know if this will be useful, but in most cases I could think of for something like this, I'd put a file in /etc/profile.d/ defining the variable(s) needed for this tool / service / whatever.  This is sourced for login shells, and can be specified as an EnvironmentFile for the systemd service.

Thank you. You are right and we already took your advice. The variable is now defined in a file in /etc/profile.d/. It gets sourced from there by /etc/bash.bashrc so everything that depends on that keeps working. But now I can source that file for systemd units too.

As far as what it is for, it is a per-device GUID that is used by a number of internal scripts. It should be available system-wide.

Even though I have a working solution for the current systemd unit to source it, I am still interested in making that GUID available to all systemd units via this mechanism:

Creating the "/etc/systemd/system.conf.d/10-default-env.conf" file will set default environment variables for all systemd units.

I will try sourcing it in 10-default-env.conf now, but I cannot find any info (yet) about whether changes to files in /etc/systemd/system.conf.d/ require a reboot. (That would make my testing a lot harder). I tried systemctl daemon-reload and it doesn't seem to make the new variables available (or I am doing something wrong).

Offline

#9 2020-11-01 20:50:08

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,516
Website

Re: using environment variables in script run by systemd unit

MountainX wrote:

The variable is now defined in a file in /etc/profile.d/. It gets sourced from there by /etc/bash.bashrc

There is no reason to source it!  Again bashrc is for interactive sessions.  Everything in profile.d/ is already sourced by /etc/profile at login.


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#10 2020-11-01 20:57:21

MountainX
Member
Registered: 2016-02-08
Posts: 371

Re: using environment variables in script run by systemd unit

Trilby wrote:
MountainX wrote:

The variable is now defined in a file in /etc/profile.d/. It gets sourced from there by /etc/bash.bashrc

There is no reason to source it!  Again bashrc is for interactive sessions.  Everything in profile.d/ is already sourced by /etc/profile at login.

Well, not "everything". Only files ending in ".sh" are sourced by /etc/profile.

Also, and most relevant to the question, my understanding is that the things that are sourced by /etc/profile are not available to systemd units. I think I read that yesterday and I will look for a reference now...
EDIT:

Normally systemd services have only a limited set of environment variables, and things in /etc/profile, /etc/profile.d and bashrc-related files are not set.

I believe I read that in the official systemd docs, but the quote is from: https://unix.stackexchange.com/a/455283/15010

I'm most interested in knowing how to make variables defined in a file (in /etc/profile.d/) available to all systemd units. What do you suggest is the right way? Thanks again.

Last edited by MountainX (2020-11-01 21:02:37)

Offline

#11 2020-11-01 22:20:37

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,516
Website

Re: using environment variables in script run by systemd unit

Yes, you still need to use an EnvironmentFile directive to source the file for systemd - my previous post was only suggesting not to source it from bashrc as well - that is unneeded, and in some cases could be problematic.


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

Board footer

Powered by FluxBB