【问题标题】:How to write a shell script to find PID and Kill如何编写一个shell脚本来查找PID和Kill
【发布时间】:2015-05-28 18:55:28
【问题描述】:

我正在尝试编写一个脚本来查找之前运行的另一个脚本的 PID。一旦找到该PID,它就会发送一个终止信号。

我可以找到 PID,但没有处理终止信号,我收到一条返回消息,表明它不是 PID。

这是我正在做的事情:

#!/bin/bash   
 PID=`ps -eaf | grep "start.sh" | awk '{print $2}'`
    echo "$PID"    
    if [[ -z "$PID" ]];
     then(
            echo "Start script is not running!"
    )else(
            kill -9 $PID
    )fi

它试图杀死的脚本会启动许多其他脚本,所以我希望杀死 start.sh 会杀死所有子进程。

【问题讨论】:

  • 您是否考虑过使用killall 命令按名称而不是按PID 杀死进程?
  • 你知道pkill吗?
  • 我试过“killall start.sh”,它返回“找不到进程”。这就是我试图杀死 PID 的原因。
  • Shell 脚本不使用( 和) 来分隔这样的块。删除它们。还要避免使用 ALL_CAPS 变量。它们通常保留给 shell/系统使用(也通常用于导出的变量)。
  • 我也尝试过 pkill ,但这不是处理它。当我运行 top 时,它仍然显示为正在运行。

标签: linux bash shell unix


【解决方案1】:

当你运行时

ps -eaf | grep "start.sh" | awk '{print $2}'

您创建了一个包含单词start.sh 的子shell。然后grep 会选择它自己的进程和start.sh 一个,所以你会得到两个PID。

这意味着当你试图杀死 start.sh 和

ps -eaf | grep "start.sh" | awk '{print $2}'

进程。 start.sh 将死,但另一个将不再存在,因此无法被杀死,因此它会给您一个错误。

如果你要拆分命令,你可能会更幸运:

PIDS=$(ps -eaf)
PID=$(echo "$PIDS" | grep "start.sh" | awk '{print $2}')

【讨论】:

  • 一种更常见的方法是使用与自身不匹配的 grep 模式;例如,[s]tart[.]sh 匹配 start.sh 但不匹配自身;这样你就不需要在 shell 变量中缓冲输出了。
  • ...也就是说,到目前为止,更好的做法是弄清楚为什么 pkill 不适用于 OP 并修复它。 :)
  • 我仍然认为[s]tart[.]sh 将匹配两个进程,但 pkill 没有/没有工作,因为它捕获要杀死的 PID 的进程之一已经结束,所以当它试图杀死时它,它不在那里,所以它出错了。
  • 啊。如果愿意,可以随时使用pgrep 并自行杀死。不,[s]tart[.]sh 不会同时匹配两者,因为 [s] 只匹配 s;它与文字字符串 [s] 不匹配。
  • 啊,是的,尽管它通过了。这很聪明:P 是的 pgrep 是一个选项,我这样做是因为它最接近 OP 原始问题,它可以帮助他们理解为什么会发生更多......我希望:D
【解决方案2】:

尝试使用pgrep:

PID=$(pgrep yourprocesname)

【讨论】:

  • pgrep <yourprocessname> | xargs -i{} kill -9 {}
  • 如果你有pgrep,你也应该有pkill,并且应该直接使用它。 linux.die.net/man/1/pkill
【解决方案3】:

这是另一个可能对某人有用的解决方案:

#!/bin/bash  
kill-process-by-name(){  
   processes=$(ps -A)
   kill -9 `echo "$processes" | grep "$1" | cut -f2 -d" "`
}

kill-process-by-name "start.sh"

【讨论】:

  • 定义函数但从不调用它的脚本有什么用?
  • @CharlesDuffy 添加了对该函数的调用。想法是您将其放在脚本的顶部并根据需要调用它。这样,如果您的脚本决定杀死多个进程,您将不会有重复的代码。
  • 这里也没有针对发现和杀死grep start.sh 进程的保护措施,而不是start.sh 进程。
  • @CharlesDuffy 这是一个非常好的观点。我已确保在执行 grep 命令之前评估 ps 命令。
  • (引用我的资料——pubs.opengroup.org/onlinepubs/009695399/utilities/…;“在参数扩展后 [...] 外壳程序将扫描在字段的双引号中未出现的扩展和替换的结果分裂")
【解决方案4】:

您可以使用pidof 而不是ps -ef

PID=`pidof start.sh | awk '{print $1}'`
echo "$PID csshst will be stopped"
if [[ -z "$PID" ]]; then
(
        kill -9 $PID
)
fi

【讨论】:

  • 在回答时,重要的是要解释它是如何工作的以及为什么它应该是选定的答案。我们想要教育,而不仅仅是扔掉代码,这样人们就知道如果问题再次发生如何解决。
【解决方案5】:
trashPID=`pidof start.sh | awk '{print $1}'`
echo "$PID csshst will be stopped"
if [[ -z "$PID" ]]; then
(
        kill -9 $PID
)
fi

纯粹

【讨论】:

  • 在回答时,重要的是要解释它是如何工作的以及为什么它应该是选定的答案。我们想要教育,而不仅仅是扔掉代码,这样人们就知道如果问题再次发生如何解决。
猜你喜欢
  • 2020-07-22
  • 2012-06-16
  • 2012-08-22
  • 2012-02-23
  • 1970-01-01
  • 2011-06-24
  • 2010-12-24
  • 2012-12-29
  • 1970-01-01
相关资源
最近更新 更多