From 82651d5b6b20ef959252e0a6845b906788235c70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 5 Jan 2021 11:17:14 +0100 Subject: [PATCH 1/3] man: improve description of environment block creation This adds a general description of "philosphy" of keeping the environemnt block small and hints about systemd-run -P env. The list of generated variables is split out to a subsection. Viewing the patch with ignoring whitespace changes is recommended. We don't ignore invalid assignments (except in import-environment to some extent), previous description was wrong. For https://bugzilla.redhat.com/show_bug.cgi?id=1912046#c17. --- man/systemctl.xml | 10 +- man/systemd.exec.xml | 715 ++++++++++++++++++++++--------------------- 2 files changed, 372 insertions(+), 353 deletions(-) diff --git a/man/systemctl.xml b/man/systemctl.xml index c83c9c49af..47bb608459 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -1123,10 +1123,12 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err Import all, one or more environment variables set on the client into the systemd manager - environment block. If no arguments are passed, the entire environment block is imported. - Otherwise, a list of one or more environment variable names should be passed, whose client-side - values are then imported into the manager's environment block. This command will silently ignore - any assignments which do not conform to the rules listed above. + environment block. If a list of environment variable names is passed, client-side values are then + imported into the manager's environment block. If any names are not valid environment variable + names or have invalid values according to the rules described above, an error is raised. If no + arguments are passed, the entire environment block inherited by the systemctl + process is imported. In this mode, any inherited invalid environment variables are quietly + ignored. diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 4b85f914f4..a9d863bfda 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -2304,10 +2304,10 @@ SystemCallErrorNumber=EPERM set by the service manager itself (such as $NOTIFY_SOCKET and such), or set by a PAM module (in case PAMName= is used). - - See environ7 for details - about environment variables. + See "Environment Variables in Spawned Processes" below for a description of how those + settings combine to form the inherited environment. See environ7 for general + information about environment variables. @@ -2809,7 +2809,7 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy - Environment variables in spawned processes + Environment Variables in Spawned Processes Processes started by the service manager are executed with an environment variable block assembled from multiple sources. Processes started by the system service manager generally do not inherit environment variables @@ -2822,410 +2822,427 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy Variables globally configured for the service manager, using the DefaultEnvironment= setting in - systemd-system.conf5, the kernel command line option systemd.setenv= (see - systemd1) or via - systemctl set-environment (see systemctl1). + systemd-system.conf5, + the kernel command line option systemd.setenv= understood by + systemd1, or via + systemctl1 + set-environment verb. - Variables defined by the service manager itself (see the list below) + Variables defined by the service manager itself (see the list below). - Variables set in the service manager's own environment variable block (subject to PassEnvironment= for the system service manager) + Variables set in the service manager's own environment variable block (subject to + PassEnvironment= for the system service manager). - Variables set via Environment= in the unit file + Variables set via Environment= in the unit file. - Variables read from files specified via EnvironmentFile= in the unit file + Variables read from files specified via EnvironmentFile= in the unit + file. Variables set by any PAM modules in case PAMName= is in effect, cf. pam_env8 + project='man-pages'>pam_env8. + - If the same environment variables are set by multiple of these sources, the later source — according to the - order of the list above — wins. Note that as final step all variables listed in - UnsetEnvironment= are removed again from the compiled environment variable list, immediately + If the same environment variable is set by multiple of these sources, the later source — according + to the order of the list above — wins. Note that as the final step all variables listed in + UnsetEnvironment= are removed from the compiled environment variable list, immediately before it is passed to the executed process. - The following environment variables are set or propagated by the service manager for each invoked - process: + The general philosophy is to expose a small curated list of environment variables to processes. + Services started by the system manager (PID 1) will be started, without additional service-specific + configuration, with just a few environment variables. The user manager inherits environment variables as + any other system service, but in addition may receive additional environment variables from PAM, and, + typically, additional imported variables when the user starts a graphical session. It is recommended to + keep the environment blocks in both the system and user managers managers lean. - - - $PATH + Hint: systemd-run -P env and systemd-run --user -P env print + the effective system and user service environment blocks. - Colon-separated list of directories to use when launching - executables. systemd uses a fixed value of - /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin - in the system manager. When compiled for systems with "unmerged /usr" (/bin is - not a symlink to /usr/bin), - :/sbin:/bin is appended. In case of the - the user manager, a different path may be configured by the distribution. It is recommended to not - rely on the order of entries, and have only one program with a given name in - $PATH. - + + Environment Variables Set or Propagated by the Service Manager - - $LANG + The following environment variables are propagated by the service manager or generated internally + for each invoked process: - Locale. Can be set in - locale.conf5 - or on the kernel command line (see - systemd1 - and - kernel-command-line7). - - + + + $PATH - - $USER - $LOGNAME - $HOME - $SHELL + Colon-separated list of directories to use when launching + executables. systemd uses a fixed value of + /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin + in the system manager. When compiled for systems with "unmerged /usr/" + (/bin is not a symlink to /usr/bin), + :/sbin:/bin is appended. In case of + the the user manager, a different path may be configured by the distribution. It is recommended to + not rely on the order of entries, and have only one program with a given name in + $PATH. + - User name (twice), home directory, and the - login shell. The variables are set for the units that have - User= set, which includes user - systemd instances. See - passwd5. - - + + $LANG - - $INVOCATION_ID + Locale. Can be set in locale.conf5 + or on the kernel command line (see + systemd1 and + kernel-command-line7). + + - Contains a randomized, unique 128bit ID identifying each runtime cycle of the unit, formatted - as 32 character hexadecimal string. A new ID is assigned each time the unit changes from an inactive state into - an activating or active state, and may be used to identify this specific runtime cycle, in particular in data - stored offline, such as the journal. The same ID is passed to all processes run as part of the - unit. - + + $USER + $LOGNAME + $HOME + $SHELL - - $XDG_RUNTIME_DIR + User name (twice), home directory, and the + login shell. The variables are set for the units that have + User= set, which includes user + systemd instances. See + passwd5. + + - The directory to use for runtime objects (such as IPC objects) and volatile state. Set for all - services run by the user systemd instance, as well as any system services that use - PAMName= with a PAM stack that includes pam_systemd. See below and - pam_systemd8 for more - information. - + + $INVOCATION_ID - - $RUNTIME_DIRECTORY - $STATE_DIRECTORY - $CACHE_DIRECTORY - $LOGS_DIRECTORY - $CONFIGURATION_DIRECTORY + Contains a randomized, unique 128bit ID identifying each runtime cycle of the unit, formatted + as 32 character hexadecimal string. A new ID is assigned each time the unit changes from an inactive state into + an activating or active state, and may be used to identify this specific runtime cycle, in particular in data + stored offline, such as the journal. The same ID is passed to all processes run as part of the + unit. + - Absolute paths to the directories defined with - RuntimeDirectory=, StateDirectory=, - CacheDirectory=, LogsDirectory=, and - ConfigurationDirectory= when those settings are used. - - + + $XDG_RUNTIME_DIR - - $CREDENTIALS_DIRECTORY + The directory to use for runtime objects (such as IPC objects) and volatile state. Set for all + services run by the user systemd instance, as well as any system services that use + PAMName= with a PAM stack that includes pam_systemd. See below and + pam_systemd8 for more + information. + - An absolute path to the per-unit directory with credentials configured via - LoadCredential=/SetCredential=. The directory is marked - read-only and is placed in unswappable memory (if supported and permitted), and is only accessible to - the UID associated with the unit via User= or DynamicUser= (and - the superuser). - + + $RUNTIME_DIRECTORY + $STATE_DIRECTORY + $CACHE_DIRECTORY + $LOGS_DIRECTORY + $CONFIGURATION_DIRECTORY - - $MAINPID + Absolute paths to the directories defined with + RuntimeDirectory=, StateDirectory=, + CacheDirectory=, LogsDirectory=, and + ConfigurationDirectory= when those settings are used. + + - The PID of the unit's main process if it is - known. This is only set for control processes as invoked by - ExecReload= and similar. - + + $CREDENTIALS_DIRECTORY - - $MANAGERPID + An absolute path to the per-unit directory with credentials configured via + LoadCredential=/SetCredential=. The directory is marked + read-only and is placed in unswappable memory (if supported and permitted), and is only accessible to + the UID associated with the unit via User= or DynamicUser= (and + the superuser). + - The PID of the user systemd - instance, set for processes spawned by it. - + + $MAINPID - - $LISTEN_FDS - $LISTEN_PID - $LISTEN_FDNAMES + The PID of the unit's main process if it is + known. This is only set for control processes as invoked by + ExecReload= and similar. + - Information about file descriptors passed to a - service for socket activation. See - sd_listen_fds3. - - + + $MANAGERPID - - $NOTIFY_SOCKET + The PID of the user systemd + instance, set for processes spawned by it. + - The socket - sd_notify() talks to. See - sd_notify3. - - + + $LISTEN_FDS + $LISTEN_PID + $LISTEN_FDNAMES - - $WATCHDOG_PID - $WATCHDOG_USEC + Information about file descriptors passed to a + service for socket activation. See + sd_listen_fds3. + + - Information about watchdog keep-alive notifications. See - sd_watchdog_enabled3. - - + + $NOTIFY_SOCKET - - $TERM + The socket + sd_notify() talks to. See + sd_notify3. + + - Terminal type, set only for units connected to - a terminal (StandardInput=tty, - StandardOutput=tty, or - StandardError=tty). See - termcap5. - - + + $WATCHDOG_PID + $WATCHDOG_USEC - - $LOG_NAMESPACE + Information about watchdog keep-alive notifications. See + sd_watchdog_enabled3. + + - Contains the name of the selected logging namespace when the - LogNamespace= service setting is used. - + + $TERM - - $JOURNAL_STREAM + Terminal type, set only for units connected to + a terminal (StandardInput=tty, + StandardOutput=tty, or + StandardError=tty). See + termcap5. + + - If the standard output or standard error output of the executed processes are connected to the - journal (for example, by setting StandardError=journal) $JOURNAL_STREAM - contains the device and inode numbers of the connection file descriptor, formatted in decimal, separated by a - colon (:). This permits invoked processes to safely detect whether their standard output or - standard error output are connected to the journal. The device and inode numbers of the file descriptors should - be compared with the values set in the environment variable to determine whether the process output is still - connected to the journal. Note that it is generally not sufficient to only check whether - $JOURNAL_STREAM is set at all as services might invoke external processes replacing their - standard output or standard error output, without unsetting the environment variable. + + $LOG_NAMESPACE - If both standard output and standard error of the executed processes are connected to the journal via a - stream socket, this environment variable will contain information about the standard error stream, as that's - usually the preferred destination for log data. (Note that typically the same stream is used for both standard - output and standard error, hence very likely the environment variable contains device and inode information - matching both stream file descriptors.) + Contains the name of the selected logging namespace when the + LogNamespace= service setting is used. + - This environment variable is primarily useful to allow services to optionally upgrade their used log - protocol to the native journal protocol (using - sd_journal_print3 and other - functions) if their standard output or standard error output is connected to the journal anyway, thus enabling - delivery of structured metadata along with logged messages. - + + $JOURNAL_STREAM - - $SERVICE_RESULT + If the standard output or standard error output of the executed processes are connected to the + journal (for example, by setting StandardError=journal) $JOURNAL_STREAM + contains the device and inode numbers of the connection file descriptor, formatted in decimal, separated by a + colon (:). This permits invoked processes to safely detect whether their standard output or + standard error output are connected to the journal. The device and inode numbers of the file descriptors should + be compared with the values set in the environment variable to determine whether the process output is still + connected to the journal. Note that it is generally not sufficient to only check whether + $JOURNAL_STREAM is set at all as services might invoke external processes replacing their + standard output or standard error output, without unsetting the environment variable. - Only defined for the service unit type, this environment variable is passed to all - ExecStop= and ExecStopPost= processes, and encodes the service - "result". Currently, the following values are defined: + If both standard output and standard error of the executed processes are connected to the journal via a + stream socket, this environment variable will contain information about the standard error stream, as that's + usually the preferred destination for log data. (Note that typically the same stream is used for both standard + output and standard error, hence very likely the environment variable contains device and inode information + matching both stream file descriptors.) - - Defined <varname>$SERVICE_RESULT</varname> values - - - - - - Value - Meaning - - + This environment variable is primarily useful to allow services to optionally upgrade their used log + protocol to the native journal protocol (using + sd_journal_print3 and other + functions) if their standard output or standard error output is connected to the journal anyway, thus enabling + delivery of structured metadata along with logged messages. + - - - success - The service ran successfully and exited cleanly. - - - protocol - A protocol violation occurred: the service did not take the steps required by its unit configuration (specifically what is configured in its Type= setting). - - - timeout - One of the steps timed out. - - - exit-code - Service process exited with a non-zero exit code; see $EXIT_CODE below for the actual exit code returned. - - - signal - A service process was terminated abnormally by a signal, without dumping core. See $EXIT_CODE below for the actual signal causing the termination. - - - core-dump - A service process terminated abnormally with a signal and dumped core. See $EXIT_CODE below for the signal causing the termination. - - - watchdog - Watchdog keep-alive ping was enabled for the service, but the deadline was missed. - - - start-limit-hit - A start limit was defined for the unit and it was hit, causing the unit to fail to start. See systemd.unit5's StartLimitIntervalSec= and StartLimitBurst= for details. - - - resources - A catch-all condition in case a system operation failed. - - - -
+ + $SERVICE_RESULT - This environment variable is useful to monitor failure or successful termination of a service. Even - though this variable is available in both ExecStop= and ExecStopPost=, it - is usually a better choice to place monitoring tools in the latter, as the former is only invoked for services - that managed to start up correctly, and the latter covers both services that failed during their start-up and - those which failed during their runtime.
-
+ Only defined for the service unit type, this environment variable is passed to all + ExecStop= and ExecStopPost= processes, and encodes the service + "result". Currently, the following values are defined: - - $EXIT_CODE - $EXIT_STATUS + + Defined <varname>$SERVICE_RESULT</varname> values + + + + + + Value + Meaning + + - Only defined for the service unit type, these environment variables are passed to all - ExecStop=, ExecStopPost= processes and contain exit status/code - information of the main process of the service. For the precise definition of the exit code and status, see - wait2. $EXIT_CODE - is one of exited, killed, - dumped. $EXIT_STATUS contains the numeric exit code formatted as string - if $EXIT_CODE is exited, and the signal name in all other cases. Note - that these environment variables are only set if the service manager succeeded to start and identify the main - process of the service. + + + success + The service ran successfully and exited cleanly. + + + protocol + A protocol violation occurred: the service did not take the steps required by its unit configuration (specifically what is configured in its Type= setting). + + + timeout + One of the steps timed out. + + + exit-code + Service process exited with a non-zero exit code; see $EXIT_CODE below for the actual exit code returned. + + + signal + A service process was terminated abnormally by a signal, without dumping core. See $EXIT_CODE below for the actual signal causing the termination. + + + core-dump + A service process terminated abnormally with a signal and dumped core. See $EXIT_CODE below for the signal causing the termination. + + + watchdog + Watchdog keep-alive ping was enabled for the service, but the deadline was missed. + + + start-limit-hit + A start limit was defined for the unit and it was hit, causing the unit to fail to start. See systemd.unit5's StartLimitIntervalSec= and StartLimitBurst= for details. + + + resources + A catch-all condition in case a system operation failed. + + + +
- - Summary of possible service result variable values - - - - - - - $SERVICE_RESULT - $EXIT_CODE - $EXIT_STATUS - - + This environment variable is useful to monitor failure or successful termination of a service. Even + though this variable is available in both ExecStop= and ExecStopPost=, it + is usually a better choice to place monitoring tools in the latter, as the former is only invoked for services + that managed to start up correctly, and the latter covers both services that failed during their start-up and + those which failed during their runtime. + - - - success - killed - HUP, INT, TERM, PIPE - - - exited - 0 - - - protocol - not set - not set - - - exited - 0 - - - timeout - killed - TERM, KILL - - - exited - 0, 1, 2, 3, …, 255 - - - exit-code - exited - 1, 2, 3, …, 255 - - - signal - killed - HUP, INT, KILL, … - - - core-dump - dumped - ABRT, SEGV, QUIT, … - - - watchdog - dumped - ABRT - - - killed - TERM, KILL - - - exited - 0, 1, 2, 3, …, 255 - - - exec-condition - exited - 1, 2, 3, 4, …, 254 - - - oom-kill - killed - TERM, KILL - - - start-limit-hit - not set - not set - - - resources - any of the above - any of the above - - - Note: the process may be also terminated by a signal not sent by systemd. In particular the process may send an arbitrary signal to itself in a handler for any of the non-maskable signals. Nevertheless, in the timeout and watchdog rows above only the signals that systemd sends have been included. Moreover, using SuccessExitStatus= additional exit statuses may be declared to indicate clean termination, which is not reflected by this table. - - - -
+ + $EXIT_CODE + $EXIT_STATUS -
-
+ Only defined for the service unit type, these environment variables are passed to all + ExecStop=, ExecStopPost= processes and contain exit status/code + information of the main process of the service. For the precise definition of the exit code and status, see + wait2. $EXIT_CODE + is one of exited, killed, + dumped. $EXIT_STATUS contains the numeric exit code formatted as string + if $EXIT_CODE is exited, and the signal name in all other cases. Note + that these environment variables are only set if the service manager succeeded to start and identify the main + process of the service. - - $PIDFILE + + Summary of possible service result variable values + + + + + + + $SERVICE_RESULT + $EXIT_CODE + $EXIT_STATUS + + - The path to the configured PID file, in case the process is forked off on behalf of a - service that uses the PIDFile= setting, see - systemd.service5 - for details. Service code may use this environment variable to automatically generate a PID file at - the location configured in the unit file. This field is set to an absolute path in the file - system. - + + + success + killed + HUP, INT, TERM, PIPE + + + exited + 0 + + + protocol + not set + not set + + + exited + 0 + + + timeout + killed + TERM, KILL + + + exited + 0, 1, 2, 3, …, 255 + + + exit-code + exited + 1, 2, 3, …, 255 + + + signal + killed + HUP, INT, KILL, … + + + core-dump + dumped + ABRT, SEGV, QUIT, … + + + watchdog + dumped + ABRT + + + killed + TERM, KILL + + + exited + 0, 1, 2, 3, …, 255 + + + exec-condition + exited + 1, 2, 3, 4, …, 254 + + + oom-kill + killed + TERM, KILL + + + start-limit-hit + not set + not set + + + resources + any of the above + any of the above + + + Note: the process may be also terminated by a signal not sent by systemd. In particular the process may send an arbitrary signal to itself in a handler for any of the non-maskable signals. Nevertheless, in the timeout and watchdog rows above only the signals that systemd sends have been included. Moreover, using SuccessExitStatus= additional exit statuses may be declared to indicate clean termination, which is not reflected by this table. + + + +
+ -
+ + $PIDFILE + + The path to the configured PID file, in case the process is forked off on behalf of + a service that uses the PIDFile= setting, see + systemd.service5 + for details. Service code may use this environment variable to automatically generate a PID file at + the location configured in the unit file. This field is set to an absolute path in the file + system. + + +
+ + For system services, when PAMName= is enabled and pam_systemd is part + of the selected PAM stack, additional environment variables defined by systemd may be set for + services. Specifically, these are $XDG_SEAT, $XDG_VTNR, see + pam_systemd8 for details. + - For system services, when PAMName= is enabled and pam_systemd is part - of the selected PAM stack, additional environment variables defined by systemd may be set for - services. Specifically, these are $XDG_SEAT, $XDG_VTNR, see - pam_systemd8 for details.
- Process exit codes + Process Exit Codes When invoking a unit process the service manager possibly fails to apply the execution parameters configured with the settings above. In that case the already created service process will exit with a non-zero exit code From 32854f70447db074635d33abc9d94756072d63b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 5 Jan 2021 11:24:03 +0100 Subject: [PATCH 2/3] systemctl: deprecate blanket import-environment Importing the full environment is convenient, but it doesn't work too well in practice, because we get a metric ton of shell-specific crap that should never end up in the global environment block: $ systemctl --user show-environment ... SHELL=/bin/zsh AUTOJUMP_ERROR_PATH=/home/zbyszek/.local/share/autojump/errors.log AUTOJUMP_SOURCED=1 CONDA_SHLVL=0 CVS_RSH=ssh DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus DESKTOP_SESSION=gnome DISPLAY=:0 FPATH=/usr/share/Modules/init/zsh-functions:/usr/local/share/zsh/site-functions:/usr/share/zsh/site-functions:/usr/share/zsh/5.8/functions GDMSESSION=gnome GDM_LANG=en_US.UTF-8 GNOME_SETUP_DISPLAY=:1 GUESTFISH_INIT=$'\\e[1;34m' GUESTFISH_OUTPUT=$'\\e[0m' GUESTFISH_PS1=$'\\[\\e[1;32m\\]>\\[\\e[0;31m\\] ' GUESTFISH_RESTORE=$'\\e[0m' HISTCONTROL=ignoredups HISTSIZE=1000 LOADEDMODULES= OLDPWD=/home/zbyszek PWD=/home/zbyszek QTDIR=/usr/lib64/qt-3.3 QTINC=/usr/lib64/qt-3.3/include QTLIB=/usr/lib64/qt-3.3/lib QT_IM_MODULE=ibus SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS=0 SESSION_MANAGER=local/unix:@/tmp/.ICE-unix/2612,unix/unix:/tmp/.ICE-unix/2612 SHLVL=0 STEAM_FRAME_FORCE_CLOSE=1 TERM=xterm-256color USERNAME=zbyszek WISECONFIGDIR=/usr/share/wise2/ ... Plenty of shell-specific and terminal-specific stuff that have no global significance. Let's start warning when this is used to push people towards importing only specific variables. Putative NEWS entry: * systemctl import-environment will now emit a warning when called without any arguments (i.e. to import the full environment block of the called program). This command will usually be invoked from a shell, which means that it'll inherit a bunch of variables which are specific to that shell, and usually to the tty the shell is connected to, and don't have any meaning in the global context of the system or user service manager. Instead, only specific variables should be imported into the manager environment block. Similarly, programs which update the manager environment block by directly calling the D-Bus API of the manager, should also push specific variables, and not the full inherited environment. --- man/systemctl.xml | 7 ++++++- man/systemd.exec.xml | 3 ++- src/systemctl/systemctl-set-environment.c | 4 ++-- src/systemctl/systemctl.c | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/man/systemctl.xml b/man/systemctl.xml index 47bb608459..27207fcf49 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -1118,7 +1118,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err import-environment - VARIABLE… + VARIABLE… @@ -1129,6 +1129,11 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err arguments are passed, the entire environment block inherited by the systemctl process is imported. In this mode, any inherited invalid environment variables are quietly ignored. + + Importing of the full inherited environment block (calling this command without any + arguments) is deprecated. A shell will set dozens of variables which only make sense locally and + are only meant for processes which are descendants of the shell. Such variables in the global + environment block are confusing to other processes. diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index a9d863bfda..ed8ab6205c 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -2854,7 +2854,8 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy configuration, with just a few environment variables. The user manager inherits environment variables as any other system service, but in addition may receive additional environment variables from PAM, and, typically, additional imported variables when the user starts a graphical session. It is recommended to - keep the environment blocks in both the system and user managers managers lean. + keep the environment blocks in both the system and user managers managers lean. Importing all variables + inherited by the graphical session or by one of the user shells is strongly discouraged. Hint: systemd-run -P env and systemd-run --user -P env print the effective system and user service environment blocks. diff --git a/src/systemctl/systemctl-set-environment.c b/src/systemctl/systemctl-set-environment.c index b68e6f6f66..3be2c57778 100644 --- a/src/systemctl/systemctl-set-environment.c +++ b/src/systemctl/systemctl-set-environment.c @@ -119,9 +119,9 @@ int import_environment(int argc, char *argv[], void *userdata) { return bus_log_create_error(r); if (argc < 2) { - _cleanup_strv_free_ char **copy = NULL; + log_warning("Calling import-environment without a list of variable names is deprecated."); - copy = strv_copy(environ); + _cleanup_strv_free_ char **copy = strv_copy(environ); if (!copy) return log_oom(); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 9a934badce..7fe1e4e65b 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -193,7 +193,7 @@ static int systemctl_help(void) { " show-environment Dump environment\n" " set-environment VARIABLE=VALUE... Set one or more environment variables\n" " unset-environment VARIABLE... Unset one or more environment variables\n" - " import-environment [VARIABLE...] Import all or some environment variables\n" + " import-environment VARIABLE... Import all or some environment variables\n" "\n%3$sManager State Commands:%4$s\n" " daemon-reload Reload systemd manager configuration\n" " daemon-reexec Reexecute systemd manager\n" From 341992081b6ece1adba270e239f96c9840884885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 5 Jan 2021 12:34:28 +0100 Subject: [PATCH 3/3] shell-completion: fix systemctl set/unset/import-environment unset-environment is completed with variable names in the environment block. set-environment the same, but suffixed with "=". import-environment is completed with variable names in the client environment. --- shell-completion/bash/systemctl.in | 11 ++++++++++- shell-completion/zsh/_systemctl.in | 5 +++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in index f6be3827cf..b26381a324 100644 --- a/shell-completion/bash/systemctl.in +++ b/shell-completion/bash/systemctl.in @@ -320,11 +320,20 @@ _systemctl () { elif __contains_word "$verb" ${VERBS[JOBS]}; then comps=$( __systemctl $mode list-jobs | { while read -r a b; do echo " $a"; done; } ) - elif __contains_word "$verb" ${VERBS[ENVS]}; then + elif [ "$verb" = 'unset-environment' ]; then + comps=$( __systemctl $mode show-environment \ + | while read -r line; do echo " ${line%%=*}"; done ) + compopt -o nospace + + elif [ "$verb" = 'set-environment' ]; then comps=$( __systemctl $mode show-environment \ | while read -r line; do echo " ${line%%=*}="; done ) compopt -o nospace + elif [ "$verb" = 'import-environment' ]; then + COMPREPLY=( $(compgen -A variable -- "$cur_orig") ) + return 0 + elif __contains_word "$verb" ${VERBS[FILE]}; then comps=$( compgen -A file -- "$cur" ) compopt -o filenames diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in index 4830aeba5f..22c40898e3 100644 --- a/shell-completion/zsh/_systemctl.in +++ b/shell-completion/zsh/_systemctl.in @@ -365,6 +365,11 @@ for fun in set-environment unset-environment ; do } done +(( $+functions[_systemctl_import-environment] )) || _systemctl_import-environment() +{ + _parameters +} + (( $+functions[_systemctl_link] )) || _systemctl_link() { _sd_unit_files }