'\" t .TH "SYSTEMD\&.ENVIRONMENT\-GENERATOR" "7" "" "systemd 252" "systemd.environment-generator" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" systemd.environment-generator \- systemd environment file generators .SH "SYNOPSIS" .HP \w'\fB/lib/systemd/system\-environment\-generators/some\-generator\fR\ 'u \fB/lib/systemd/system\-environment\-generators/some\-generator\fR .HP \w'\fB/usr/lib/systemd/user\-environment\-generators/some\-generator\fR\ 'u \fB/usr/lib/systemd/user\-environment\-generators/some\-generator\fR .PP .nf /run/systemd/system\-environment\-generators/* /etc/systemd/system\-environment\-generators/* /usr/local/lib/systemd/system\-environment\-generators/* /lib/systemd/system\-environment\-generators/* .fi .PP .nf /run/systemd/user\-environment\-generators/* /etc/systemd/user\-environment\-generators/* /usr/local/lib/systemd/user\-environment\-generators/* /usr/lib/systemd/user\-environment\-generators/* .fi .sp .SH "DESCRIPTION" .PP Generators are small executables that live in /lib/systemd/system\-environment\-generators/ and other directories listed above\&. \fBsystemd\fR(1) will execute those binaries very early at the startup of each manager and at configuration reload time, before running the generators described in \fBsystemd.generator\fR(7) and before starting any units\&. Environment generators can override the environment that the manager exports to services and other processes\&. .PP Generators are loaded from a set of paths determined during compilation, as listed above\&. System and user environment generators are loaded from directories with names ending in system\-environment\-generators/ and user\-environment\-generators/, respectively\&. Generators found in directories listed earlier override the ones with the same name in directories lower in the list\&. A symlink to /dev/null or an empty file can be used to mask a generator, thereby preventing it from running\&. Please note that the order of the two directories with the highest priority is reversed with respect to the unit load path, and generators in /run/ overwrite those in /etc/\&. .PP After installing new generators or updating the configuration, \fBsystemctl daemon\-reload\fR may be executed\&. This will re\-run all generators, updating environment configuration\&. It will be used for any services that are started subsequently\&. .PP Environment file generators are executed similarly to unit file generators described in \fBsystemd.generator\fR(7), with the following differences: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Generators are executed sequentially in the alphanumerical order of the final component of their name\&. The output of each generator output is immediately parsed and used to update the environment for generators that run after that\&. Thus, later generators can use and/or modify the output of earlier generators\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Generators are run by every manager instance, their output can be different for each user\&. .RE .PP It is recommended to use numerical prefixes for generator names to simplify ordering\&. .SH "EXAMPLES" .PP \fBExample\ \&1.\ \&A simple generator that extends an environment variable if a directory exists in the file system\fR .sp .if n \{\ .RS 4 .\} .nf # 50\-xdg\-data\-dirs\&.sh #!/bin/sh # SPDX\-License\-Identifier: MIT\-0 # set the default value XDG_DATA_DIRS="${XDG_DATA_DIRS:\-/usr/local/share/:/usr/share}" # add a directory if it exists if [ \-d /opt/foo/share ]; then XDG_DATA_DIRS="/opt/foo/share:${XDG_DATA_DIRS}" fi # write our output echo "XDG_DATA_DIRS=${XDG_DATA_DIRS}" .fi .if n \{\ .RE .\} .PP \fBExample\ \&2.\ \&A more complicated generator which reads existing configuration and mutates one variable\fR .sp .if n \{\ .RS 4 .\} .nf # 90\-rearrange\-path\&.py #!/usr/bin/env python3 # SPDX\-License\-Identifier: MIT\-0 """ Proof\-of\-concept systemd environment generator that makes sure that bin dirs are always after matching sbin dirs in the path\&. (Changes /sbin:/bin:/foo/bar to /bin:/sbin:/foo/bar\&.) This generator shows how to override the configuration possibly created by earlier generators\&. It would be easier to write in bash, but let\*(Aqs have it in Python just to prove that we can, and to serve as a template for more interesting generators\&. """ import os import pathlib def rearrange_bin_sbin(path): """Make sure any pair of \&.../bin, \&.../sbin directories is in this order >>> rearrange_bin_sbin(\*(Aq/bin:/sbin:/usr/sbin:/usr/bin\*(Aq) \*(Aq/bin:/sbin:/usr/bin:/usr/sbin\*(Aq """ items = [pathlib\&.Path(p) for p in path\&.split(\*(Aq:\*(Aq)] for i in range(len(items)): if \*(Aqsbin\*(Aq in items[i]\&.parts: ind = items[i]\&.parts\&.index(\*(Aqsbin\*(Aq) bin = pathlib\&.Path(*items[i]\&.parts[:ind], \*(Aqbin\*(Aq, *items[i]\&.parts[ind+1:]) if bin in items[i+1:]: j = i + 1 + items[i+1:]\&.index(bin) items[i], items[j] = items[j], items[i] return \*(Aq:\*(Aq\&.join(p\&.as_posix() for p in items) if __name__ == \*(Aq__main__\*(Aq: path = os\&.environ[\*(AqPATH\*(Aq] # This should be always set\&. # If it\*(Aqs not, we\*(Aqll just crash, which is OK too\&. new = rearrange_bin_sbin(path) if new != path: print(\*(AqPATH={}\*(Aq\&.format(new)) .fi .if n \{\ .RE .\} .PP \fBExample\ \&3.\ \&Debugging a generator\fR .sp .if n \{\ .RS 4 .\} .nf SYSTEMD_LOG_LEVEL=debug VAR_A=something VAR_B="something else" \e /lib/systemd/system\-environment\-generators/path\-to\-generator .fi .if n \{\ .RE .\} .SH "SEE ALSO" .PP \fBsystemd-environment-d-generator\fR(8), \fBsystemd.generator\fR(7), \fBsystemd\fR(1), \fBsystemctl\fR(1)