diff options
Diffstat (limited to 'nixpkgs/nixos/doc/manual/from_md/development/writing-modules.chapter.xml')
-rw-r--r-- | nixpkgs/nixos/doc/manual/from_md/development/writing-modules.chapter.xml | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/nixpkgs/nixos/doc/manual/from_md/development/writing-modules.chapter.xml b/nixpkgs/nixos/doc/manual/from_md/development/writing-modules.chapter.xml index e33c24f4f12c..367731eda090 100644 --- a/nixpkgs/nixos/doc/manual/from_md/development/writing-modules.chapter.xml +++ b/nixpkgs/nixos/doc/manual/from_md/development/writing-modules.chapter.xml @@ -122,6 +122,25 @@ services) and <literal>systemd.timers</literal> (the list of commands to be executed periodically by <literal>systemd</literal>). </para> + <para> + Care must be taken when writing systemd services using + <literal>Exec*</literal> directives. By default systemd performs + substitution on <literal>%<char></literal> specifiers in these + directives, expands environment variables from + <literal>$FOO</literal> and <literal>${FOO}</literal>, splits + arguments on whitespace, and splits commands on + <literal>;</literal>. All of these must be escaped to avoid + unexpected substitution or splitting when interpolating into an + <literal>Exec*</literal> directive, e.g. when using an + <literal>extraArgs</literal> option to pass additional arguments to + the service. The functions + <literal>utils.escapeSystemdExecArg</literal> and + <literal>utils.escapeSystemdExecArgs</literal> are provided for + this, see <link linkend="exec-escaping-example">Example: Escaping in + Exec directives</link> for an example. When using these functions + system environment substitution should <emphasis>not</emphasis> be + disabled explicitly. + </para> <anchor xml:id="locate-example" /> <para> <emphasis role="strong">Example: NixOS Module for the @@ -184,6 +203,36 @@ in { }; } </programlisting> + <anchor xml:id="exec-escaping-example" /> + <para> + <emphasis role="strong">Example: Escaping in Exec + directives</emphasis> + </para> + <programlisting language="bash"> +{ config, lib, pkgs, utils, ... }: + +with lib; + +let + cfg = config.services.echo; + echoAll = pkgs.writeScript "echo-all" '' + #! ${pkgs.runtimeShell} + for s in "$@"; do + printf '%s\n' "$s" + done + ''; + args = [ "a%Nything" "lang=\${LANG}" ";" "/bin/sh -c date" ]; +in { + systemd.services.echo = + { description = "Echo to the journal"; + wantedBy = [ "multi-user.target" ]; + serviceConfig.Type = "oneshot"; + serviceConfig.ExecStart = '' + ${echoAll} ${utils.escapeSystemdExecArgs args} + ''; + }; +} +</programlisting> <xi:include href="option-declarations.section.xml" /> <xi:include href="option-types.section.xml" /> <xi:include href="option-def.section.xml" /> |