有什么快速而简单的方法可以确保在给定时间内只有一个shell脚本实例在运行?


当前回答

又快又脏?

#!/bin/sh

if [ -f sometempfile ]
  echo "Already running... will now terminate."
  exit
else
  touch sometempfile
fi

..do what you want here..

rm sometempfile

其他回答

在flock(2)系统调用周围有一个包装器,毫无想象力地称为flock(1)。这使得可靠地获得独占锁相对容易,而不必担心清理等问题。手册页上有一些关于如何在shell脚本中使用它的示例。

迟来的派对,使用来自@Majal的想法,这是我的脚本,只启动emacsclient GUI的一个实例。有了它,我可以设置快捷键打开或跳回相同的瘦弱。我有另一个脚本调用emacsclient在终端当我需要它。在这里使用emacsclient只是为了展示一个实际的例子,人们可以选择其他的东西。对于我的小脚本来说,这种方法足够快、足够好。告诉我哪里脏:)

#!/bin/bash

# if [ $(pgrep -c $(basename $0)) -lt 2 ]; then # this works but requires script name to be unique
if [ $(pidof -x "$0"|wc -w ) -lt 3 ]; then
    echo -e "Starting $(basename $0)"
    emacsclient --alternate-editor="" -c "$@"
else
    echo -e "$0 is running already"
fi
if [ 1 -ne $(/bin/fuser "$0" 2>/dev/null | wc -w) ]; then
    exit 1
fi

一些unix具有与前面提到的flock非常相似的lockfile。

从手册中:

Lockfile可以用来创建一个 或者更多的信号量文件。如果锁, 文件不能创建所有指定的 文件(在指定的顺序),它 等待睡眠时间(默认为8) 秒并重试最后一个文件 没有成功。您可以指定 直到重试的次数 返回失败。如果数字 重试次数为-1(默认值,即 -r-1)锁文件将永远重试。

这将工作,如果你的脚本名称是唯一的:

#!/bin/bash
if [ $(pgrep -c $(basename $0)) -gt 1 ]; then 
  echo $(basename $0) is already running
  exit 0
fi

如果scriptname不是唯一的,这在大多数linux发行版上都有效:

#!/bin/bash
exec 9>/tmp/my_lock_file
if ! flock -n 9  ; then
   echo "another instance of this script is already running";
   exit 1
fi

来源:http://mywiki.wooledge.org/BashFAQ/045