]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
run: expand variables also with --scope 27113/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 4 Apr 2023 19:18:33 +0000 (21:18 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 24 Apr 2023 08:02:30 +0000 (10:02 +0200)
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
src/run/run.c

index f33190f4c58bf630ca2096777f5e5386c1c1e73a..73adbfb9276cf66df12ec8acdeb757165599a296 100644 (file)
       <varlistentry>
         <term><option>--expand-environment=<replaceable>BOOL</replaceable></option></term>
 
-        <listitem><para>Expand environment variables in command arguments. If enabled (the default), the
-        service manager that spawns the actual command will expand variables specified as
-        <literal>${<replaceable>VARIABLE</replaceable>}</literal> in the same way as in commands specied via
-        <varname>ExecStart=</varname> in units. Note that this is similar to, but not the same as variable
-        expansion in
+        <listitem><para>Expand environment variables in command arguments. If enabled (the default),
+        environment variables specified as <literal>${<replaceable>VARIABLE</replaceable>}</literal> will be
+        expanded in the same way as in commands specified via <varname>ExecStart=</varname> in units. With
+        <varname>--scope</varname>, this expansion is performed by <command>systemd-run</command> 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
         <citerefentry project='man-pages'><refentrytitle>bash</refentrytitle><manvolnum>1</manvolnum></citerefentry>
         and other shells.</para>
 
index 3ad866aaa6911e30f47d2abdfaffb6b60b184f2d..2f5ec9c73b76a7072d0f54e3b6f24da20575d3ff 100644 (file)
@@ -103,8 +103,7 @@ static int help(void) {
                "     --description=TEXT           Description for unit\n"
                "     --slice=SLICE                Run in the specified slice\n"
                "     --slice-inherit              Inherit the slice\n"
-               "     --expand-environment=BOOL    Control server-side expansion of environment\n"
-               "                                  variables\n"
+               "     --expand-environment=BOOL    Control expansion of environment variables\n"
                "     --no-block                   Do not wait until operation finished\n"
                "  -r --remain-after-exit          Leave service around until explicitly stopped\n"
                "     --wait                       Wait until service stopped again\n"
@@ -1472,7 +1471,7 @@ static int start_transient_scope(sd_bus *bus) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
         _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
-        _cleanup_strv_free_ char **env = NULL, **user_env = NULL;
+        _cleanup_strv_free_ char **env = NULL, **user_env = NULL, **expanded_cmdline = NULL;
         _cleanup_free_ char *scope = NULL;
         const char *object = NULL;
         sd_id128_t invocation_id;
@@ -1614,6 +1613,13 @@ static int start_transient_scope(sd_bus *bus) {
         if (!arg_quiet)
                 log_info("Running scope as unit: %s", scope);
 
+        if (arg_expand_environment) {
+                expanded_cmdline = replace_env_argv(arg_cmdline, env);
+                if (!expanded_cmdline)
+                        return log_oom();
+                arg_cmdline = expanded_cmdline;
+        }
+
         execvpe(arg_cmdline[0], arg_cmdline, env);
 
         return log_error_errno(errno, "Failed to execute: %m");