以下是我的脚本'Infinite.sh'代码,我在后台运行此脚本,在运行此脚本之前,我想要杀死所有以前的实例。 但这也是杀死我的实例。
kill -9 `ps ux|grep Infinite.sh|awk -F\ '{print $2}'`
while true;
do
echo -n "SLEEPING FOR 5 SECOND"
date
sleep 5
done
答案 0 :(得分:4)
只需消除当前流程'列表中的PID。要做到这一点,只需对代码进行最小的更改:
kill -9 `ps ux | grep Infinite.sh | awk -F\ -v pid=$$ 'pid != $2 {print $2}'`
选项-v pid=$$
将awk变量pid
设置为当前进程的值'进程ID。表达式pid != $2 {print $2}
仅在与当前流程不同时才会打印流程ID。进程ID。
为了简化代码,我们可以使用pgrep
:
kill -9 $(pgrep Infinite.sh | grep -v $$)
正如三联在评论中指出的那样, kill -9
应仅用作最后的手段。 -9
(SIGKILL)阻止进程自行清理,删除可能首先尝试尝试的其他信号包括-2
(SIGINT),-6
(SIGABRT)或-15
(SIGTERM,这是默认值)。至于使用哪些信号,Randal L. Schwartz建议:
一般情况下,发送15,等待一两秒,如果不是这样的话 工作,发送2,如果这不起作用,发送1.如果不是, 删除二进制文件是因为该程序表现不佳!
有关应避免kill -9
原因的详细信息,请参阅here。有关各种Unix信号及其含义的更多信息,请参阅wikipedia
答案 1 :(得分:2)
任何事情都可能是危险的。更好的解决方案是每次运行实例时将PID保存到文件中。如果存在PID文件,并且该文件中的PID是有效的并且是活动进程,则终止该进程。保存当前进程的PID。
PID_FILE=/var/run/infinite.pid
# Read saved PID of previous instance.
read PID < "$PID_FILE"
# You may consider other safer signals like TERM, HUP, QUIT, and ABRT.
# Checking may also be optional. You can just send the signal right away.
kill -s 0 "$PID" &>/dev/null && kill -s 9 "$PID" &>/dev/null
# Optionally wait for process to exit.
sleep 2s
# Optionally check it again.
kill -s 0 "$PID" &>/dev/null && { echo "Unable to kill process $PID."; exit; }
# Save PID.
echo "$$" > "$PID_FILE"
答案 2 :(得分:1)
只需检查pid是否与正在运行的脚本相同。
这样的事情可行:
#!/bin/bash
pids=($(pgrep "$(basename "$0")"))
for i in "${pids[@]}"
do
(( $$ != i)) && kill "$i"
done
while :; do sleep 1;done
~