systemd has an EnvironmentFile
directive, which sets environment variables from a file’s contents based on a number of rules, which are not quite equivalent to how a shell would parse that file.
How can I parse a systemd EnvironmentFile
in exactly the same way that systemd itself would?
Advertisement
Answer
The surest thing is to let systemd parse the file itself, via a transient service. Thus:
# emit a NUL-delimited set of key=value definitions for environment variables defined by a set of files newVarsForFile_nullsep() { local -a extraParams=( ); local file (( $# )) || return 0 # no files specified, nothing to do for file in "$@"; do extraParams+=( --property=EnvironmentFile="$file" ) done comm -z -23 <(sort -z < <(systemd-run --user --pipe "${extraParams[@]}" grep -zvE '^INVOCATION_ID=' /proc/self/environ </dev/null)) <(sort -z < <(systemd-run --user --pipe grep -zvE '^INVOCATION_ID=' /proc/self/environ </dev/null) ) } # emit code that can be eval'd in an instance of bash to precisely define the exact variables newVarsForFile_shellscript() { while IFS= read -r -d '' vardef; do printf '%s=%qn' "${vardef%%=*}" "${vardef#*=}" done < <(newVarsForFile_nullsep "$@") }
Thereafter, one may invoke (as an example):
newVarsForFile_shellscript /etc/conf.d/*.conf
…to emit a shell script fragment which, when executed by bash, will set all the same environment variables that adding the relevant EnvironmentFile
s to a service definition would set.