如何从脚本本身检查脚本是否正在运行?

7

以下是一个示例脚本 sample.sh

#!/bin/bash

if ps aux | grep -o "sample.sh" >/dev/null
then
    echo "Already script running"
    exit 0
fi

echo "start script"

while true
do
    echo "script running"
    sleep 5
done

在上述脚本中,我想要检查此脚本之前是否已经运行过,如果已经运行,则不再运行。
问题在于检查条件总是变为真(因为检查条件需要运行脚本),并且它总是显示 "Already script running" 消息。
有什么办法可以解决这个问题吗?
5个回答

10

您需要一个合适的锁。我建议使用flock命令,像这样:

exec 201> /tmp/lock.$(basename $0).file
if ! flock -n 201  ; then
  echo "another instance of $0 is running";
  exit 1
fi

# cmds 

exec 201>&- 
rm -rf  /tmp/lock.$(basename $0).file

这基本上创建了一个用于脚本的锁,使用一个临时文件。该临时文件有特定的意义,除了用于告知您的脚本是否已获取锁之外。 当程序的一个实例正在运行时,同一程序的下一次运行将无法运行,因为锁将阻止它。


删除程序中的锁定是无害的,因为一旦程序退出,锁定将自动释放。我倾向于删除我创建的临时文件。 - P.P
但是它显示了一个错误,如下:./sample.sh: line 3: /tmp/lock../sample.sh.file: No such file or directory flock: 201: Bad file descriptor - Jayesh Bhoi
是的,你说得对。现在它正在工作。还有一个问题,如果脚本意外终止或停止运行,锁定文件会自动删除吗? - Jayesh Bhoi
1
@Jayesh 如果脚本因任何原因而死亡,锁定仍将被释放。 锁定文件将保持不变(不会被删除),但这不会造成任何问题。 - P.P
2
这是最好的方法,当我看到它时,立即参考了@Blue Moon的代码并在之前编写的现有脚本中更新,该脚本需要相同的功能,但我用了太长的脚本。 - BMW
显示剩余4条评论

1

对我来说,使用锁文件会更安全,在进程启动时创建它,在完成后删除。


1
让脚本将自己的PID记录在文件中。在此之前,它首先检查该文件是否已包含活动PID,如果是,则退出。
pid=$(< ${PID_FILE:?} || exit
kill -0 $PID && exit

下一个练习是在写入文件时防止竞态条件。

0

试试这个,它会返回用户运行的 sample.sh 的数量

ps -aux | awk -v app='sample.sh' '$0 ~ app { print $1 }' |grep $USERNAME|wc -l

0

将一个临时文件写入/tmp目录。 让你的脚本检查文件是否存在,如果存在则不运行。

#!/bin/sh

# our tmpfile
tmpfile="/tmp/mytmpfile"

# check to see if it exists.
# if it does then exit script
if [[ -f ${tmpfile} ]]; then
echo script already running.
exit
fi

# it doesn't exist at this point so lets make one 
touch ${tmpfile}

# do whatever now.

# end of script
rm ${tmpfile}

如果我的脚本意外终止,那么它将不会删除临时文件。 - Jayesh Bhoi
您可以将PID名称包含在文件名中,或者将其写入临时文件。如果进程崩溃,则新进程将具有不同的PID。 - Vaibhav

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接