在 systemd 服务中忽略命令的返回状态

Mih*_*hai 3 systemd exit-status

我有以下问题,我正在编写一个创建 fifo 设备文件的脚本,但即使文件已经存在,我也想返回 true。以下代码段试图从||和 中创建fifos /bin/true。我怎么能告诉mkfifocmd 最后一个参数是X

$ /usr/bin/mkfifo /dev/fifofile || /bin/true
Run Code Online (Sandbox Code Playgroud)

在 systemd 服务中运行它:

ExecStartPre=/usr/bin/mkfifo /dev/fifofile || /bin/true
Run Code Online (Sandbox Code Playgroud)
Apr 29 08:39:40  mkfifo[27275]: /usr/bin/mkfifo: cannot create fifo '/dev/fifofile': File exists
Apr 29 08:39:40  mkfifo[27275]: /usr/bin/mkfifo: cannot create fifo '||': File exists
Apr 29 08:39:40  mkfifo[27275]: /usr/bin/mkfifo: cannot create fifo '/bin/true': File exists
Run Code Online (Sandbox Code Playgroud)

尝试更改ExecStartPretoExecStartPre=(/usr/bin/mkfifo /dev/fifofile) || /bin/true会出现以下错误:

 Executable path is not absolute: (/usr/bin/mkfifo /dev/gpsfifo) || /bin/true
Run Code Online (Sandbox Code Playgroud)

ilk*_*chu 7

ExecStartPre=/usr/bin/mkfifo /dev/fifofile || /bin/true
Run Code Online (Sandbox Code Playgroud)

这作为 shell 命令行很好,但 systemd 不ExecStartPre通过 shell运行命令等。(我不确定是否需要mkfifo和的路径true

文件说的是:

每个命令行都使用 systemd.syntax(5) 中“引用”部分中描述的规则不加引号。第一项成为要执行的命令,后续项成为参数。

该语法受shell语法启发,但仅理解以下段落中描述的元字符和扩展,并且变量的扩展不同。具体来说,不支持使用“<”、“<<”、“>”和“>>”的重定向,使用“|”的管道,使用“&”在后台运行程序以及其他shell语法元素

但是由于引号应该起作用,您可以使用类似的东西显式运行外壳

ExecStartPre=sh -c 'mkfifo /dev/fifofile || true'. 
Run Code Online (Sandbox Code Playgroud)

但是,这应该不是必需的,因为 systemd 具有用于忽略错误的特殊语法。

如果可执行路径以“-”为前缀,则记录通常被认为失败的命令的退出代码(即非零退出状态或由于信号异常退出),但没有进一步的影响,被认为等同于成功。

所以就

ExecStartPre=-mkfifo /dev/fifofile
Run Code Online (Sandbox Code Playgroud)

应该做。

不过,我不确定不可避免的错误消息,因为关于重定向的说明只提到了>,而不是2>。但是您也可以先删除文件然后重新创建它:

ExecStartPre=-rm -f /dev/fifofile
ExecStartPre=-mkfifo /dev/fifofile
Run Code Online (Sandbox Code Playgroud)

或者也许像

ExecStartPre=-rm -f /dev/fifofile ; mkfifo /dev/fifofile
Run Code Online (Sandbox Code Playgroud)

但我没有测试。此外,这当然会使任何其他具有相同名称的文件失效。

如果你想防范这种情况,你可以这样做:

ExecStartPre=sh -c '[ -p /dev/fifofile ] || mkfifo /dev/fifofile'
Run Code Online (Sandbox Code Playgroud)

如果管道已经存在,那应该静默退出,但是mkfifo如果文件存在并且还不是管道,则会出现错误。

可能还有一个更“正确”的地方来放置 fifo 文件。