我有以下问题,我正在编写一个创建 fifo 设备文件的脚本,但即使该文件已经存在,我也想返回 true。以下代码片段也尝试从||
和创建 fifo /bin/true
。我怎样才能告诉mkfifo
cmd最后一个参数是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
尝试更改ExecStartPre
为ExecStartPre=(/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 文件。