bash 如何检查我的 shell 脚本的另一个实例是否正在运行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16807876/
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
How to check if another instance of my shell script is running
提问by Jatin Bodarya
GNU bash, version 1.14.7(1)
GNU bash,版本 1.14.7(1)
I have a script is called "abc.sh
"
I have to check this from abc.sh
script only...
inside it I have written following statement
我有一个名为“ abc.sh
”的abc.sh
脚本,我只能从脚本中检查它......在里面我写了以下语句
status=`ps -efww | grep -w "abc.sh" | grep -v grep | grep -v $$ | awk '{ print }'`
if [ ! -z "$status" ]; then
echo "[`date`] : abc.sh : Process is already running"
exit 1;
fi
I know it's wrong because every time it exits as it found its own process in 'ps'
how to solve it?
how can I check that script is already running or not from that script
only ?
我知道这是错误的,因为每次它退出时都在“ps”中找到自己的进程如何解决?如何检查脚本是否已经在运行from that script
?
回答by Austin Phillips
An easier way to check for a process already executing is the pidof
command.
检查已经在执行的进程的一种更简单的方法是pidof
命令。
if pidof -x "abc.sh" >/dev/null; then
echo "Process already running"
fi
Alternatively, have your script create a PID file when it executes. It's then a simple exercise of checking for the presence of the PID file to determine if the process is already running.
或者,让您的脚本在执行时创建一个 PID 文件。然后是检查PID 文件是否存在以确定进程是否已在运行的简单练习。
#!/bin/bash
# abc.sh
mypidfile=/var/run/abc.sh.pid
# Could add check for existence of mypidfile here if interlock is
# needed in the shell script itself.
# Ensure PID file is removed on program exit.
trap "rm -f -- '$mypidfile'" EXIT
# Create a file with current PID to indicate that process is running.
echo $$ > "$mypidfile"
...
Update:The question has now changed to check from the script itself. In this case, we would expect to always see at least one abc.sh
running. If there is more than one abc.sh
, then we know that process is still running. I'd still suggest use of the pidof
command which would return 2 PIDs if the process was already running. You could use grep
to filter out the current PID, loop in the shell or even revert to just counting PIDs with wc
to detect multiple processes.
更新:问题现在已更改为从脚本本身检查。在这种情况下,我们希望总是看到至少一个abc.sh
运行。如果有多个abc.sh
,那么我们知道该进程仍在运行。pidof
如果进程已经在运行,我仍然建议使用将返回 2 个 PID的命令。您可以使用grep
过滤掉当前的 PID,在 shell 中循环,甚至恢复到仅计算 PIDwc
以检测多个进程。
Here's an example:
下面是一个例子:
#!/bin/bash
for pid in $(pidof -x abc.sh); do
if [ $pid != $$ ]; then
echo "[$(date)] : abc.sh : Process is already running with PID $pid"
exit 1
fi
done
回答by Aba
I you want the "pidof" method, here is the trick:
我想要“pidof”方法,这是诀窍:
if pidof -o %PPID -x "abc.sh">/dev/null; then
echo "Process already running"
fi
Where the -o %PPID
parameter tells to omit the pid of the calling shell or shell script. More info in the pidof
man page.
凡-o %PPID
参数告诉省略调用shell或shell脚本的PID。pidof
手册页中的更多信息。
回答by twalberg
Here's one trick you'll see in various places:
这是您会在不同地方看到的一个技巧:
status=`ps -efww | grep -w "[a]bc.sh" | awk -vpid=$$ ' != pid { print }'`
if [ ! -z "$status" ]; then
echo "[`date`] : abc.sh : Process is already running"
exit 1;
fi
The brackets around the [a]
(or pick a different letter) prevent grep
from finding itself. This makes the grep -v grep
bit unnecessary. I also removed the grep -v $$
and fixed the awk
part to accomplish the same thing.
周围的括号[a]
(或选择不同的字母)可防止grep
找到自己。这使得该grep -v grep
位变得不必要。我还移除grep -v $$
并固定了awk
零件以完成同样的事情。
回答by glenn Hymanman
Someone please shoot me down if I'm wrong here
如果我错了,请有人打我
I understand that the mkdir
operation is atomic, so you could create a lock directory
我知道mkdir
操作是原子的,所以你可以创建一个锁定目录
#!/bin/sh
lockdir=/tmp/AXgqg0lsoeykp9L9NZjIuaqvu7ANILL4foeqzpJcTs3YkwtiJ0
mkdir $lockdir || {
echo "lock directory exists. exiting"
exit 1
}
# take pains to remove lock directory when script terminates
trap "rmdir $lockdir" EXIT INT KILL TERM
# rest of script here
回答by Carlo Miguel Cruz
Here's how I do it in a bash script:
这是我如何在 bash 脚本中执行此操作:
if ps ax | grep ps -eaf | grep -v grep | grep $PROCESS | grep -v $$
| grep -v $$ | grep bash | grep -v grep
then
echo "The script is already running."
exit 1
fi
This allows me to use this snippet for any bash script. I needed to grep bash because when using with cron, it creates another process that executes it using /bin/sh.
这允许我将此代码段用于任何 bash 脚本。我需要 grep bash 因为当与 cron 一起使用时,它会创建另一个使用 /bin/sh 执行它的进程。
回答by Sridhar Kumar N
Use the PS command in a little different way to ignore child process as well:
以稍微不同的方式使用 PS 命令来忽略子进程:
for pid in $(pgrep -f my_script.sh); do
if [ $pid != $$ ]; then
echo "[$(date)] : my_script.sh : Process is already running with PID $pid"
exit 1
else
echo "Running with PID $pid"
fi
done
回答by Scott H
pidof
wasn't working for me so I searched some more and came across pgrep
pidof
对我不起作用,所以我搜索了更多并遇到了 pgrep
if pidof -x "`basename MY_SCRIPT_NAME=`basename "#!/bin/sh
# check if lock file exists
if [ -e /tmp/script.lock ]; then
echo "script is already running"
else
# create a lock file
touch /tmp/script.lock
echo "run script..."
#remove lock file
rm /tmp/script.lock
fi
"`
if pidof -o %PPID -x $MY_SCRIPT_NAME > /dev/null; then
echo "$MY_SCRIPT_NAME already running; exiting"
exit 1
fi
`" -o $$ >/dev/null; then
echo "Process already running"
fi
Taken in part from answers above and https://askubuntu.com/a/803106/802276
回答by Andrei Neagoe
I find the answer from @Austin Phillips is spot on. One small improvement I'd do is to add -o (to ignore the pid of the script itself) and match for the script with basename (ie same code can be put into any script):
我发现@Austin Phillips 的答案恰到好处。我要做的一个小改进是添加 -o(忽略脚本本身的 pid)并使用 basename 匹配脚本(即相同的代码可以放入任何脚本中):
##代码##回答by Cloud Artisans
I didn't want to hardcode abc.sh
in the check, so I used the following:
我不想abc.sh
在支票中硬编码,所以我使用了以下内容:
回答by Cleber Reizen
I create a temporary file during execution.
我在执行期间创建了一个临时文件。
This is how I do it:
这就是我的做法:
##代码##