5

我正在使用 sshj 并试图跟踪文件,但我的问题是远程进程永远不会被杀死。

在以下示例代码中,您可以看到我尝试跟踪 /var/log/syslog,然后向进程发送终止信号。但是,在应用程序停止并列出服务器上的所有进程后,我仍然可以看到一个活动的尾进程。

为什么这段代码不会杀死进程?我能做些什么来补救呢?

    SSHClient ssh = new SSHClient();
    ssh.addHostKeyVerifier(new PromiscuousVerifier());
    try {           
        ssh.connect("localhost");
        ssh.authPassword("xxx", "xxx");
        final Session session = ssh.startSession();
        try {
            final Command cmd = session.exec("tail -f /var/log/syslog");
            cmd.signal(Signal.KILL);
            System.out.println("\n** exit status: " + cmd.getExitStatus());
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            session.close();
        }
    } finally{
        ssh.disconnect();
    }

编辑

还尝试发送所有可用信号。

            for(Signal s : Signal.values()){
                cmd.signal(s);
            }
4

4 回答 4

6

分配 PTY 并发送 Ctrl+C 字符代码对我有用:

final Session session = ssh.startSession();
session.allocateDefaultPTY();
try {
    final Command cmd = session.exec("tail -f /var/log/syslog");

    // Send Ctrl+C (character code is 0x03):
    cmd.getOutputStream().write(3);
    cmd.getOutputStream().flush();

    // Wait some time for the process to exit:
    cmd.join(1, TimeUnit.SECONDS);

    // If no exception has been raised yet, then the process has exited
    // (but the exit status can still be null if the process has been killed).
    System.out.println("\n** exit status: " + cmd.getExitStatus());
} catch (IOException e) {
    e.printStackTrace();
}finally{
    session.close();
}

当然,能够发送信号会更好,但如果连 OpenSSH 服务器都不支持,那就没有希望了 :/

于 2013-11-14T18:49:09.430 回答
3

openssh 不支持https://bugzilla.mindrot.org/show_bug.cgi?id=1424

只需使用 cmd.close(),这也应该称为过程

于 2011-09-07T20:08:26.913 回答
2

这很可能是 ssh 服务器实现的问题,因为我尝试使用两个不同的 ssh 客户端并获得相同的结果。我的解决方案最终成为客户端尾部逻辑,而不是“tail -f”以防止自由漫游进程。

于 2011-09-09T14:03:55.940 回答
1

最近有一个类似的问题。在我的具体情况下,这是@shikhar 提到的 OpenSSH 问题。

我的解决方案是运行启动另一个会话(共享连接)并运行 kill command pgrep mycommand | xargs kill

于 2013-01-17T15:08:12.127 回答