summaryrefslogtreecommitdiff
path: root/man
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2023-04-24 22:03:06 +0200
committerGitHub <noreply@github.com>2023-04-24 22:03:06 +0200
commit208a59c15fd41f87248a1a981e558acd3de5e47b (patch)
tree45f73492212a2c220305ab41bb3c74cd6265efeb /man
parent91ce42f008764c3c6d8d72c5fb3b72d0945b7de2 (diff)
parent2ed7a221fafb25eea937c4e86fb88ee501dba51e (diff)
downloadsystemd-208a59c15fd41f87248a1a981e558acd3de5e47b.tar.gz
Merge pull request #27113 from keszybz/variable-expansion-rework
Rework serialization of command lines in pid1 and make run not expand variables
Diffstat (limited to 'man')
-rw-r--r--man/systemd-run.xml63
1 files changed, 62 insertions, 1 deletions
diff --git a/man/systemd-run.xml b/man/systemd-run.xml
index cd9e50d5b8..73adbfb927 100644
--- a/man/systemd-run.xml
+++ b/man/systemd-run.xml
@@ -92,6 +92,11 @@
Consider using the <option>exec</option> service type (i.e. <option>--property=Type=exec</option>) to
ensure that <command>systemd-run</command> returns successfully only if the specified command line has
been successfully started.</para>
+
+ <para>After <command>systemd-run</command> passes the command to the service manager, the manager
+ performs variable expansion. This means that dollar characters (<literal>$</literal>) which should not be
+ expanded need to be escaped as <literal>$$</literal>. Expansion can also be disabled using
+ <varname>--expand-environment=no</varname>.</para>
</refsect1>
<refsect1>
@@ -170,6 +175,25 @@
</varlistentry>
<varlistentry>
+ <term><option>--expand-environment=<replaceable>BOOL</replaceable></option></term>
+
+ <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>
+
+ <para>See
+ <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for a description of variable expansion. Disabling variable expansion is useful if the specified
+ command includes or may include a <literal>$</literal> sign.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-r</option></term>
<term><option>--remain-after-exit</option></term>
@@ -529,11 +553,48 @@ There is a screen on:
</example>
<example>
+ <title>Variable expansion by the manager</title>
+
+ <programlisting>$ systemd-run -t echo "&lt;${INVOCATION_ID}>" '&lt;${INVOCATION_ID}>'
+ &lt;> &lt;5d0149bfa2c34b79bccb13074001eb20>
+ </programlisting>
+
+ <para>The first argument is expanded by the shell (double quotes), but the second one is not expanded
+ by the shell (single quotes). <command>echo</command> is called with [<literal>/usr/bin/echo</literal>,
+ <literal>[]</literal>, <literal>[${INVOCATION_ID}]</literal>] as the argument array, and then
+ <command>systemd</command> generates <varname>${INVOCATION_ID}</varname> 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.</para>
+ </example>
+
+ <example>
+ <title>Variable expansion and output redirection using a shell</title>
+
+ <para>Variable expansion by <command>systemd</command> can be disabled with
+ <varname>--expand-environment=no</varname>.</para>
+
+ <para>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:</para>
+
+ <programlisting>$ systemd-run --expand-environment=no -t bash \
+ -c 'echo $SHELL $$ >/dev/stdout'
+/bin/bash 12345
+ </programlisting>
+
+ <para>The last argument is passed verbatim to the <command>bash</command> shell which is started by the
+ service unit. The shell expands <literal>$SHELL</literal> to the path of the shell, and
+ <literal>$$</literal> to its process number, and then those strings are passed to the
+ <command>echo</command> built-in and printed to standard output (which in this case is connected to the
+ calling terminal).</para>
+ </example>
+
+ <example>
<title>Return value</title>
<programlisting>$ 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 $$$$'</programlisting>
+$ systemd-run --user --wait -p SuccessExitStatus=SIGUSR1 --expand-environment=no \
+ bash -c 'kill -SIGUSR1 $$'</programlisting>
<para>Those three invocations will succeed, i.e. terminate with an exit code of 0.</para>
</example>