The parser is borrowed from systemd
v256
as is. Despite the original parser slightly oversimplify and allows to do weird things,
see tests.
Common approach is to use environment variables to configure golang
programs.
And systemd
is the most widespread system and service manager.
It is convenient to use literally the same file as environment holder at debugging time and
right as EnvironmentFile
in systemd
.service
-file.
There are two seporate things here: (i) library to parse EnvironmentFile
format and (ii) ready to use binary tool
to run any processes with environment variables from given file.
echo 'TEST = "OK"' >xenv.env
xenv sh -c 'echo $TEST'
OK
The XENV
environment variable can be set to tell xenv
where to look for certain .env
-files.
xenv
will use the first matched file.
echo 'TEST = "OK"' >custom.env
export XENV=/tmp/x.env:./custom.env
xenv sh -c 'echo $TEST'
OK
Install in standard go way
go install github.com/michurin/systemd-env-file/cmd/xenv@latest
The binary will be installed in the directory named by the GOBIN
environment variable,
which defaults to $GOPATH/bin
or $HOME/go/bin
if the GOPATH
environment variable is not set.
Build manually and install to custom place
go build ./cmd/...
install xenv /opt/bin # use your favorite options
go get github.com/michurin/systemd-env-file/@latest
import "github.com/michurin/systemd-env-file/sdenv"
You can play with it at go online playground.
Similar to
Environment=
, but reads the environment variables from a text file. The text file should contain newline-separated variable assignments. Empty lines, lines without an=
separator, or lines starting with;
or#
will be ignored, which may be used for commenting. The file must be UTF-8 encoded. Valid characters are unicode scalar values other than noncharacters,U+0000
NUL
, andU+FEFF
byte order mark. Control codes other thanNUL
are allowed.In the file, an unquoted value after the
=
is parsed with the same backslash-escape rules as unquoted text in a POSIX shell, but unlike in a shell, interior whitespace is preserved and quotes after the first non-whitespace character are preserved. Leading and trailing whitespace (space, tab, carriage return) is discarded, but interior whitespace within the line is preserved verbatim. A line ending with a backslash will be continued to the following one, with the newline itself discarded. A backslash\
followed by any character other than newline will preserve the following character, so that\\
will become the value\
.In the file, a
'
-quoted value after the=
can span multiple lines and contain any character verbatim other than single quote, like single-quoted text in a POSIX shell. No backslash-escape sequences are recognized. Leading and trailing whitespace outside of the single quotes is discarded.In the file, a
"
-quoted value after the=
can span multiple lines, and the same escape sequences are recognized as in double-quoted text of a POSIX shell. Backslash (\
) followed by any of"
\
`
$
will preserve that character. A backslash followed by newline is a line continuation, and the newline itself is discarded. A backslash followed by any other character is ignored; both the backslash and the following character are preserved verbatim. Leading and trailing whitespace outside of the double quotes is discarded.The argument passed should be an absolute filename or wildcard expression, optionally prefixed with
-
, which indicates that if the file does not exist, it will not be read and no error or warning message is logged. This option may be specified more than once in which case all specified files are read. If the empty string is assigned to this option, the list of file to read is reset, all prior assignments have no effect.The files listed with this directive will be read shortly before the process is executed (more specifically, after all processes from a previous unit state terminated. This means you can generate these files in one unit state, and read it with this option in the next. The files are read from the file system of the service manager, before any file system changes like bind mounts take place).
Settings from these files override settings made with
Environment=
. If the same variable is set twice from these files, the files will be read in the order they are specified and the later setting will override the earlier setting.
You can find examples at playground, in documentation and the most detailed in tests.
-d
for debugging- Go doc
- Consider docker compose's parser API. Mimic it's interface?
- Export environment in docker compose format?
parse_env_file_internal
—systemd
implementation- Useful constants: [1], [2]