确保只有一个脚本实例正在运行?

确保只有一个脚本实例正在运行?

代码:

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 指出的:“在任何情况下使用pidofbasedbasename $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 分配给不同的程序。当然,没有一个解决方案是完美的。但这离我原来的问题太远了。

相关内容