From f872ddd182bd33d9ba0569d050374b9b9a9a2ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 2 Apr 2023 23:17:58 +0200 Subject: run: add --expand-environment=no to disable server-side envvar expansion This uses StartExecEx to get the equivalent of ExecStart=:. StartExecEx was added in b3d593673c5b8b0b7d781fd26ab2062ca6e7dbdb, so this will not work with older systemds. A hint is emitted if we get an error indicating lack of support. PID1 returns SD_BUS_ERROR_PROPERTY_READ_ONLY, but I'm checking for SD_BUS_ERROR_UNKNOWN_PROPERTY too for safety. --- man/systemd-run.xml | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'man') diff --git a/man/systemd-run.xml b/man/systemd-run.xml index cd9e50d5b8..2ad68d8884 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -92,6 +92,11 @@ Consider using the service type (i.e. ) to ensure that systemd-run returns successfully only if the specified command line has been successfully started. + + After systemd-run passes the command to the service manager, the manager + performs variable expansion. This means that dollar characters ($) which should not be + expanded need to be escaped as $$. Expansion can also be disabled using + --expand-environment=no. @@ -169,6 +174,24 @@ + + + + Expand environment variables in command arguments. If enabled (the default), the + service manager that spawns the actual command will expand variables specified as + ${VARIABLE} in the same way as in commands specied via + ExecStart= in units. Note that this is similar to, but not the same as variable + expansion in + bash1 + and other shells. + + See + systemd.service5 + for a description of variable expansion. Disabling variable expansion is useful if the specified + command includes or may include a $ sign. + + + @@ -533,7 +556,8 @@ There is a screen on: $ systemd-run --user --wait true $ systemd-run --user --wait -p SuccessExitStatus=11 bash -c 'exit 11' -$ systemd-run --user --wait -p SuccessExitStatus=SIGUSR1 bash -c 'kill -SIGUSR1 $$$$' +$ systemd-run --user --wait -p SuccessExitStatus=SIGUSR1 --expand-environment=no \ + bash -c 'kill -SIGUSR1 $$' Those three invocations will succeed, i.e. terminate with an exit code of 0. -- cgit v1.2.1 From de99fadd3117d2bbe3d5fdf1c6e7b6855fccf465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 3 Apr 2023 08:26:56 +0200 Subject: man/systemd-run: add examples explaining how variable expansion is performed --- man/systemd-run.xml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'man') diff --git a/man/systemd-run.xml b/man/systemd-run.xml index 2ad68d8884..f33190f4c5 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -551,6 +551,42 @@ There is a screen on: $ loginctl enable-linger + + Variable expansion by the manager + + $ systemd-run -t echo "<${INVOCATION_ID}>" '<${INVOCATION_ID}>' + <> <5d0149bfa2c34b79bccb13074001eb20> + + + The first argument is expanded by the shell (double quotes), but the second one is not expanded + by the shell (single quotes). echo is called with [/usr/bin/echo, + [], [${INVOCATION_ID}]] as the argument array, and then + systemd generates ${INVOCATION_ID} and substitutes it in the + command-line. This substitution could not be done on the client side, because the target ID that will + be set for the service isn't known before the call is made. + + + + Variable expansion and output redirection using a shell + + Variable expansion by systemd can be disabled with + --expand-environment=no. + + Disabling variable expansion can be useful if the command to execute contains dollar characters + and escaping them would be inconvenient. For example, when a shell is used: + + $ systemd-run --expand-environment=no -t bash \ + -c 'echo $SHELL $$ >/dev/stdout' +/bin/bash 12345 + + + The last argument is passed verbatim to the bash shell which is started by the + service unit. The shell expands $SHELL to the path of the shell, and + $$ to its process number, and then those strings are passed to the + echo built-in and printed to standard output (which in this case is connected to the + calling terminal). + + Return value -- cgit v1.2.1 From 2ed7a221fafb25eea937c4e86fb88ee501dba51e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 4 Apr 2023 21:18:33 +0200 Subject: run: expand variables also with --scope This makes syntax be the same for commands which are started by the manager and those which are spawned directly (when --scope is used). Before: $ systemd-run -q -t echo '$TERM' xterm-256color $ systemd-run -q --scope echo '$TERM' $TERM Now: $ systemd-run -q --scope echo '$TERM' xterm-256color Previous behaviour can be restored via --expand-environment=no: $ systemd-run -q --scope --expand-environment=no echo '$TERM' $TERM Fixes #22948. At some level, this is a compat break. Fortunately --scope is not very widely used, so I think we can get away with this. Having different syntax depending on whether --scope was used or not was bad UX. A NEWS entry will be required. --- man/systemd-run.xml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'man') diff --git a/man/systemd-run.xml b/man/systemd-run.xml index f33190f4c5..73adbfb927 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -177,11 +177,12 @@ - Expand environment variables in command arguments. If enabled (the default), the - service manager that spawns the actual command will expand variables specified as - ${VARIABLE} in the same way as in commands specied via - ExecStart= in units. Note that this is similar to, but not the same as variable - expansion in + Expand environment variables in command arguments. If enabled (the default), + environment variables specified as ${VARIABLE} will be + expanded in the same way as in commands specified via ExecStart= in units. With + --scope, this expansion is performed by systemd-run itself, and + in other cases by the service manager that spawns the command. Note that this is similar to, but not + the same as variable expansion in bash1 and other shells. -- cgit v1.2.1