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

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

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

$ /usr/bin/mkfifo /dev/fifofile || /bin/true

在 systemd 服务中运行它:

ExecStartPre=/usr/bin/mkfifo /dev/fifofile || /bin/true
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

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

 Executable path is not absolute: (/usr/bin/mkfifo /dev/gpsfifo) || /bin/true

答案1

ExecStartPre=/usr/bin/mkfifo /dev/fifofile || /bin/true

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

文件说那:

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

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

但由于引号应该有效,您可以使用类似的命令显式运行 shell

ExecStartPre=sh -c 'mkfifo /dev/fifofile || true'. 

然而,这并不是必需的,因为 systemd 有一个特殊的语法来忽略错误。

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

所以就

ExecStartPre=-mkfifo /dev/fifofile

应该做。

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

ExecStartPre=-rm -f /dev/fifofile
ExecStartPre=-mkfifo /dev/fifofile

当然,这也会破坏任何其他同名文件。

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

ExecStartPre=sh -c '[ -p /dev/fifofile ] || mkfifo /dev/fifofile'

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

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

相关内容