我有一个脚本,我只想运行一次。如果脚本第二次被调用,我会检查它是否存在锁定文件。如果锁存文件存在,那么我想查看进程是否实际运行。
我一直在搞乱pgrep,但没有得到预期的结果:
#!/bin/bash
COUNT=$(pgrep $(basename $0) | wc -l)
PSTREE=$(pgrep $(basename $0) ; pstree -p $$)
echo "###"
echo $COUNT
echo $PSTREE
echo "###"
echo "$(basename $0) :" `pgrep -d, $(basename $0)`
echo sleeping.....
sleep 10
我得到的结果是:
$ ./test.sh
###
2
2581 2587 test.sh(2581)---test.sh(2587)---pstree(2591)
###
test.sh : 2581
sleeping.....
我不明白为什么只有一个进程实际运行时我得到“2”。
有什么想法吗?我确定这就是我打电话的方式。我已经尝试了许多不同的组合,似乎无法弄明白。
解决方案:
我最终做的是这样做(我的部分内容):
function check_lockfile {
# Check for previous lockfiles
if [ -e $LOCKFILE ]
then
echo "Lockfile $LOCKFILE already exists. Checking to see if process is actually running...." >> $LOGFILE 2>&1
# is it running?
if [ $(ps -elf | grep $(cat $LOCKFILE) | grep $(basename $0) | wc -l) -gt 0 ]
then
abort "ERROR! - Process is already running at PID: $(cat $LOCKFILE). Exitting..."
else
echo "Process is not running. Removing $LOCKFILE" >> $LOGFILE 2>&1
rm -f $LOCKFILE
fi
else
echo "Lockfile $LOCKFILE does not exist." >> $LOGFILE 2>&1
fi
}
function create_lockfile {
# Check for previous lockfile
check_lockfile
#Create lockfile with the contents of the PID
echo "Creating lockfile with PID:" $$ >> $LOGFILE 2>&1
echo -n $$ > $LOCKFILE
echo "" >> $LOGFILE 2>&1
}
# Acquire lock file
create_lockfile >> $LOGFILE 2>&1 \
|| echo "ERROR! - Failed to acquire lock!"
答案 0 :(得分:3)
pgrep的参数是扩展的正则表达式模式。
在您的情况下,命令pgrep $(basename $0)
将评估为pgrep test.sh
,其匹配任何具有test
后跟任何字符且最后跟sh
的进程匹配}。所以它会与btest8sh
,atest_shell
等匹配。
您应该创建一个锁文件。如果锁定文件存在,程序应该退出。
lock=$(basename $0).lock
if [ -e $lock ]
then
echo Process is already running with PID=`cat $lock`
exit
else
echo $$ > $lock
fi
答案 1 :(得分:0)
您已打开锁定文件。用它来让你的生活更轻松。
将进程ID写入锁定文件。当您看到锁定文件存在时,请阅读它以查看它应该锁定的进程ID,并检查该进程是否仍在运行。
然后在版本2中,您还可以编写程序名称,程序参数,程序启动时间等,以防止新进程以相同的进程ID启动。
答案 2 :(得分:0)
将它放在脚本顶部附近......
pid=$$
script=$(basename $0)
guard="/tmp/$script-$(id -nu).pid"
if test -f $guard ; then
echo >&2 "ERROR: Script already runs... own PID=$pid"
ps auxw | grep $script | grep -v grep >&2
exit 1
fi
trap "rm -f $guard" EXIT
echo $pid >$guard
是的,测试命令和echo命令之间有一个竞争条件的小窗口,可以通过附加到保护文件来修复,然后检查第一行确实是我们自己的PID。此外,if中的诊断输出可以在生产版本中注释掉。