【问题标题】:Shell Script not able to Kill ProcessShell 脚本无法终止进程
【发布时间】:2016-09-29 23:24:30
【问题描述】:

我正在使用下面的脚本来查找和终止进程,但它以某种方式无法正常工作。 如果有任何缺陷,请帮助编辑。我正在寻找 JVM。使用 AIX 机器。

    PID=`ps -eaf | grep JVM| grep -v grep | awk '{print $2}'`
    if [[ "" !=  "$PID" ]]
    then
        echo "killing $PID" 
        kill $PID
    else
        echo "PID not found"

    fi

【问题讨论】:

  • if 最好写成if [[ "x" != "x$PID" ]],这样可以确保!= 用于字符串比较(作为奖励,它还可以确保在不同的shell 上正确处理空的grep 查询)。
  • 代码看起来基本正确 - 您可以详细说明“shomehow 无法正常工作”的含义,但我们将假设该进程在杀死后幸存下来。如果 Neil Ellis 的回答对您没有帮助,您将不得不解释更多。 - 从 ps 输出 grepping 修复字符串时我所做的就像 ps -eaf | grep '[J]VM' .. 不需要 grep -v grep 因为 grep 命令与正则表达式不匹配

标签: bash shell unix process aix


【解决方案1】:

来自Wikipedia entry

在 Unix 和类 Unix 操作系统中,kill 是用于 向进程发送信号。默认情况下,发送的消息是 终止信号,它请求进程退出。但是杀是 用词不当;发送的信号可能与 进程杀死。

所以默认情况下 kill 发送 SIGTERM(相当于 kill -15)您可能需要执行 SIGKILL:

kill -9 $PID

或者如果您特别小心,或者您需要系统正常关闭,那么我建议您使用 SIGINT,因为它与键盘上的 Ctrl-C 相同。所以

kill -2 $PID

Java 应用程序恐怕doesn't always handle SIGTERM correctly 它们依赖于关闭挂钩中的良好行为。为确保应用正确处理 SIGTERM 等信号,您可以直接处理 SIGTERM 信号:

public class CatchTerm {
  public static void main(String[] args) throws Exception {
    Signal.handle(new Signal("TERM"), new SignalHandler () {
      public void handle(Signal sig) {
        //handle sigterm such as System.exit(1)

      }
    });
    Thread.sleep(86400000);
  }
}

为了完整起见,这里是common signals

| Signal  | ID  | Action    | Description          | Java
| ---     | --- | ---       | ---                  | ---
| SIGHUP  | 1   | Terminate | Hangup               | The application should reload any config            
| SIGINT  | 2   | Terminate | Ctrl-C               | Keyboard interrupt, start clean shutdown
| SIGQUIT | 3   | Terminate | Terminal quit signal | JVM traps and issues a Thread dump       
| SIGABRT | 6   | Terminate | Process abort signal | Do not handle, quit immediately             
| SIGKILL | 9   | Terminate | Kill (forced)        | Cannot be trapped                      
| SIGTERM | 15  | Terminate | Termination signal.  | Quit quickly, safe but fast                

有关更高级的流程选择,请参阅killallpkill

【讨论】:

  • SIGKILL (kill -9 ...) 通常不推荐使用,因为它无法被进程捕获,也无法进行清理。
  • 很奇怪。我删除了 sh 文件并使用相同的脚本再次创建它并且它工作。现在我有一个问题,因为这个脚本只会为 jvm 捕获一个 pid,但是在杀死一个 pid 之后,另一个 pid 正在生成。如何修改这个现有脚本以杀死所有生成的 pid 直到全部被杀死?
  • @RishuA killall JVM?
  • 当然可以,但是大多数 Java 进程的信号处理能力都很差。在使用 Java 15 年后,我还没有损坏任何东西,而且我见过的大多数 Java 生产环境也使用 -9。这更像是一个“正确性”问题,而不是实际风险。要成为一个好公民,您可以使用 SIGINT 或:- SIGINT、暂停、SIGKILL。
猜你喜欢
  • 2013-11-22
  • 1970-01-01
  • 2021-11-08
  • 2010-11-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多