在运行相同的 Unix 脚本之前终止脚本的先前实例

在运行相同的 Unix 脚本之前终止脚本的先前实例

我想终止属于我要再次运行的 shell 脚本的后台进程。

这意味着在执行 shell 脚本之前我想删除正在运行的后台进程相同的脚本。

答案1

检查同一脚本中是否存在 PID。

在脚本的开头添加以下内容:

#!/bin/bash
script_name=${BASH_SOURCE[0]}
for pid in $(pidof -x $script_name); do
    if [ $pid != $$ ]; then
        kill -9 $pid
    fi 
done

答案2

kill -9 $(pgrep -f ${BASH_SOURCE[0]} | grep -v $$)

很简单。
使用 pgrep 搜索当前运行脚本的所有实例。

pgrep 很好,因为它只返回 pid。

然后使用$$ grep出当前正在运行的pid,这样它就不会自杀。

最后kill -9 终止之前的实例。

答案3

我很早以前就在我的一个 shell 脚本中这样做过。我是这样做的:

ps aux | \
grep -P ${BASH_SOURCE[0]} | \
grep -v $$ | \
grep -P "bash" | \
grep -oP "^[[:alnum:]]+\s+\d+\s" | \
grep -oP "\d+" | \
xargs kill -9

此方法的优点在于,它不会杀死当前正在运行的脚本本身,而只会杀死它以前的实例。

演示上述方法的示例脚本是这样的:

#!/bin/bash

ps aux | grep -P ${BASH_SOURCE[0]} | grep -v $$ | grep -P "bash" | grep -oP "^[[:alnum:]]+\s+\d+\s" | grep -oP "\d+"

sleep 100

现在,在终端中运行此脚本的一个实例。然后在不同的终端中运行另一个实例。您将看到前一个实例将立即被杀死,而第二个实例运行良好。

答案4

您可以使用$0代替${BASH_SOURCE[0]}.

我不得不使用pgrep -f <filename>而不是pidof -x <filename>因为由于某种原因后者没有返回任何东西。

另外,kill -9这里不需要。

所以结果(受到@jcbermy的回答的启发):

#!/bin/bash
for pid in $(pgrep -f $0); do
    if [ $pid != $$ ]; then
        kill $pid
    fi 
done

相关内容