拥有以下示例脚本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"
消息。
知道怎么解决吗?
答案 0 :(得分:7)
你需要一个合适的锁。我会这样使用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
这基本上使用临时文件为脚本创建锁。除了用于判断脚本是否已获得锁定之外,临时文件具有特殊意义。 当有一个程序运行的实例时,同一程序的下一次运行无法运行,因为锁会阻止它。
答案 1 :(得分:1)
对我来说,使用锁定文件更安全,在进程启动时创建它,在完成后删除。
答案 2 :(得分:1)
让脚本在文件中记录自己的PID。在此之前,它首先检查该文件当前是否包含活动PID,在这种情况下它将退出。
pid=$(< ${PID_FILE:?} || exit
kill -0 $PID && exit
下一个练习是在编写文件时防止竞争条件。
答案 3 :(得分:0)
试试这个,它给出了用户运行的sample.sh数量
ps -aux | awk -v app='sample.sh' '$0 ~ app { print $1 }' |grep $USERNAME|wc -l
答案 4 :(得分:0)
将tmp文件写入/ 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}