SystemD单元文件中ExecStopPost的rm命令执行失败求助
嗨,我来帮你捋清楚这个问题~ 你遇到的坑其实是SystemD执行Exec*系列指令的特殊逻辑导致的:默认情况下,SystemD不会通过shell来解析你的命令,而是直接把内容拆成「程序+参数」的形式调用,所以像通配符*、多命令分隔符&&这类shell专属的语法,SystemD根本不会处理,直接原封不动传给rm,这就是失败的核心原因。
举个例子,你之前写的ExecStopPost=/bin/rm /tmp/nethogs.*,SystemD会把/tmp/nethogs.*当作一个完整的文件名传给rm,而不是让shell把它解析成nethogs.stdout和nethogs.stderr两个文件,rm找不到这个叫nethogs.*的文件,自然就返回失败状态1了。
给你几个可行的解决办法:
方案一:通过shell托管命令解析
把删除命令用/bin/sh -c包裹起来,让shell来处理通配符和多命令逻辑,写法如下:ExecStopPost=/bin/sh -c '/bin/rm /tmp/nethogs.stdout /tmp/nethogs.stderr'也可以用通配符简化成:
ExecStopPost=/bin/sh -c '/bin/rm /tmp/nethogs.*'方案二:加上
-f参数更稳妥
如果你担心服务异常退出时,其中某个日志文件可能没生成,可以给rm加上-f参数——这个参数会忽略不存在的文件,也不会弹出任何提示,就算文件缺失,命令也会返回0状态,避免SystemD判定为执行失败:ExecStopPost=/bin/sh -c '/bin/rm -f /tmp/nethogs.*'
另外补充一句,你之前尝试的ExecStopPost=/bin/rm /tmp/nethogs.stdout && /bin/rm /tmp/nethogs.stderr写法也走不通,因为SystemD会把整个字符串当作rm的参数,不会解析成两个连续的命令,自然达不到预期效果。
备注:内容来源于stack exchange,提问作者manifestor

