代码:
if [[ "`pidof -x $(basename $0) -o %PPID`" ]]; then exit; fi
代码原始来源:https://forum.rclone.org/t/continuous-syncing/12377/2
我不明白 bash 脚本中的这段代码如何确保 bash 脚本只有一个实例正在运行。
我了解该部分pidof -x $(basename $0)
检索脚本的进程 ID,但我不明白该部分-o %PPID
的用途。
问题:有人知道代码是如何工作的吗?
答案1
根据手册页我错过了pidof
(感谢@cas提醒我):
-o omitpid
Tells pidof to omit processes with that process id. The
special pid %PPID can be used to name the parent process
of the pidof program, in other words the calling shell or
shell script.
因此-o %PPID
意味着忽略当前正在运行的脚本,只检索该脚本的另一个实例的 PID(如果有)。
原始代码可以重写,无需混合使用反引号和 $() 进行命令替换:
#!/bin/bash
# ensure only one instance of script is running
if pidof -x $(basename $0) -o %PPID > /dev/null
then
exit
fi
更新:正如@Alfe 指出的:“在任何情况下使用pidof
basedbasename $0
都是执行此检查的不安全方式。两个截然不同的程序可以具有相同的基名......”。这是使用 pid 文件基于 @Alfe 注释的另一个解决方案:
#!/usr/bin/env bash
set -e
pid_file="fixed_name.pid"
# ensure only one instance of script is running
if [ -f "$pid_file" ] && ps -p $(cat "$pid_file") > /dev/null
then
# another instance of this script is running
exit
fi
# write script's PID to pid-file
printf "$$" > "$pid_file"
# do some work
我可以看到此解决方案中存在一个问题,因为可能会在过时的 PID 文件中将有效的 PID 分配给不同的程序。当然,没有一个解决方案是完美的。但这离我原来的问题太远了。