bash 使用 pgrep 确定进程是否正在运行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9104884/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Determining if process is running using pgrep
提问by jared
I have a script that I only want to be running one time. If the script gets called a second time I'm having it check to see if a lockfile exists. If the lockfile exists then I want to see if the process is actually running.
我有一个我只想运行一次的脚本。如果脚本第二次被调用,我会检查它是否存在锁定文件。如果锁文件存在,那么我想看看进程是否真的在运行。
I've been messing around with pgrep but am not getting the expected results:
我一直在搞 pgrep 但没有得到预期的结果:
#!/bin/bash
COUNT=$(pgrep $(basename $ ./test.sh
###
2
2581 2587 test.sh(2581)---test.sh(2587)---pstree(2591)
###
test.sh : 2581
sleeping.....
) | wc -l)
PSTREE=$(pgrep $(basename 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 lock=$(basename pid=$$
script=$(basename ##代码##)
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
).lock
if [ -e $lock ]
then
echo Process is already running with PID=`cat $lock`
exit
else
echo $$ > $lock
fi
) | 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!"
) ; pstree -p $$)
echo "###"
echo $COUNT
echo $PSTREE
echo "###"
echo "$(basename ##代码##) :" `pgrep -d, $(basename ##代码##)`
echo sleeping.....
sleep 10
The results I'm getting are:
我得到的结果是:
##代码##I don't understand why I'm getting a "2" when only one process is actually running.
我不明白为什么当只有一个进程实际运行时我会得到“2”。
Any ideas? I'm sure it's the way I'm calling it. I've tried a number of different combinations and can't quite seem to figure it out.
有任何想法吗?我确定这是我称呼它的方式。我尝试了许多不同的组合,但似乎无法弄清楚。
SOLUTION:
解决方案:
What I ended up doing was doing this (portion of my script):
我最终做的是这样做(我的脚本的一部分):
##代码##采纳答案by Shiplu Mokaddim
The argument for pgrep is an extended regular expression pattern.
In you case the command pgrep $(basename $0)will evaluate to pgrep test.shwhich will match match any process that has testfollowed by any characterand lastly followed by sh. So it wil match btest8sh, atest_shelletc.
pgrep 的参数是扩展的正则表达式模式。在您的情况下,该命令pgrep $(basename $0)将评估为pgrep test.sh哪个将匹配任何test后跟任何字符并最后跟随着sh. 所以它会匹配btest8sh,atest_shell等等。
You should create a lock file. If the lock file exists program should exit.
您应该创建一个锁定文件。如果锁定文件存在,程序应该退出。
##代码##回答by mob
You are already opening a lock file. Use it to make your life easier.
您已经在打开一个锁定文件。使用它让您的生活更轻松。
Write the process id to the lock file. When you see the lock file exists, read it to see what process id it is supposedly locking, and check to see if that process is still running.
将进程 ID 写入锁定文件。当您看到锁定文件存在时,请阅读它以查看它应该锁定的进程 ID,并检查该进程是否仍在运行。
Then in version 2, you can also write program name, program arguments, program start time, etc. to guard against the case where a new process starts with the same process id.
那么在版本2中,你还可以写程序名、程序参数、程序启动时间等,以防止新进程以相同进程id启动的情况。
回答by pyroscope
Put this near the top of your script...
把它放在你的脚本顶部附近......
##代码##And yes, there IS a small window for a race condition between the test and echo commands, which can be fixed by appending to the guard file, and then checking that the first line is indeed our own PID. Also, the diagnostic output in the if can be commented out in a production version.
是的,test 和 echo 命令之间存在一个竞争条件的小窗口,可以通过附加到保护文件来修复它,然后检查第一行是否确实是我们自己的 PID。此外,可以在生产版本中注释掉 if 中的诊断输出。

