30

I'm trying to dump the env from a systemd service unit and systemctl show-environment doesn't do what I want. Is there any way to systemctl to show me what the environment looks like inside my service?

3 Answers 3

47

If your service is running, you can use systemctl status <name>.service to identify the PID(s) of the service process(es), and then use sudo strings /proc/<PID>/environ to look at the actual environment of the process.

2
  • I don't have "strings", but also I can't start the process as the environment variable causes it to die...
    – KolonUK
    Feb 17, 2023 at 16:34
  • 1
    @KolonUK Then, either read systemctl show-environment + the contents of all Environment= statements and any files referred by EnvironmentFile= statements in systemctl cat your.service, excluding any variables listed by UnsetEnvironment= statements; or make a copy of the service definition, modify it to run a script similar to what Inetquestion suggested, run it, and check the resulting file.
    – telcoM
    Feb 17, 2023 at 19:31
0

run a script which executes 'set' within and write the output to a file.

#!/usr/bin/ksh

set >> /tmp/set-results.txt
0

Elaborating on @telcoM's answer, you can use this one-liner to dump the environment variable from a currently running single-PID service (with some adjustment you may be able to iterate through all PIDS and concatenate the results):

strings /proc/$(systemctl status <unitname>.service | grep -Po '(?<=PID: )\d+')/environ

If the service in question is failing to start, or otherwise inaccessible, systemctl has a command that allows you to see the composite of all files on disk that are used to configure the service. From the man page:

cat PATTERN...
           Show backing files of one or more units. Prints the "fragment" and
           "drop-ins" (source files) of units. Each file is preceded by a comment
           which includes the file name. Note that this shows the contents of the
           backing files on disk, which may not match the system manager's
           understanding of these units if any unit files were updated on disk and
           the daemon-reload command wasn't issued since.

So systemctl cat <unitname>.service should produce output showing the computed configuration "file". Note that, in addition to the caveat above about files updated on disk, if you have an EnvironmentFile directive you may need to go hunting for that file to get the full picture. Something like this may get you fairly close but it's a beast to type:

echo $(systemctl show-environment) $(systemctl cat <unitname>.service | grep -Po '(?<=^Environment=)[^\n]*') $(cat "$(systemctl cat <unitname>.service | grep -Po '(?<=^EnvironmentFile=-)[^\n]*')")

Breaking that down here's what we're doing:

  • systemctl show-environment -- get the current environment for systemctl
  • systemctl cat <unitname>.service | grep -Po '(?<=^Environment=)[^\n]*' -- Get the Environment directives for the unit in question
  • cat "$(systemctl cat <unitname>.service | grep -Po '(?<=^EnvironmentFile=-)[^\n]*')" -- Get the contents of the file(s) listed. If they aren't prefixed with a dash, you may need to adjust the grep pattern a bit
  • echo ... -- mash all the output above into a string. There are definitely prettier ways to do this.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .