【问题标题】:Why is "kill" different from a terminal and from system()?为什么“kill”与终端和系统()不同?
【发布时间】:2014-12-12 05:53:35
【问题描述】:

当我运行下面的脚本时,它将在远程主机上执行sleep 123,然后杀死本地 ssh 进程,这将在远程主机上退出sleep 123。这是预期的行为。

但是,如果我删除 system("kill $p") 并从具有进程 ID 的终端执行 kill 命令,则本地 ssh 被杀死,但远程 sleep 123 仍然存在。没想到。

# /usr/gnu/bin/kill 961
Killed by signal 15.

问题

为什么相同的 kill 命令会因从 Perl 的 system() 和终端执行而有所不同,以及远程 sleep 123 命令如何在 ssh 连接被终止时继续存在?

#!/usr/bin/perl    
use strict;
use warnings;
use Parallel::ForkManager;

my $pm = Parallel::ForkManager->new(5);
my $pid = $pm->start;
my $p = $pid;
if (!$pid) {
    system("ssh 10.10.47.47 sleep 123");
    $pm->finish;
}

$p = qx(/usr/bin/pgrep -P $p);
print "ssh pid is $p\n";

system("/usr/gnu/bin/kill $p");

【问题讨论】:

  • kill 是 bash 中的内置命令。我没有检查过,但它的行为可能与/usr/bin/kill/usr/gnu/bin/kill 的行为不同。
  • 您的代码中有一个令人讨厌的竞争条件。如果ssh 进程在您调用pgrepkill 之间死亡,并且新进程获得相同的PID,则您可能将kill 发送到错误的进程。
  • 我相信你错了。
  • 交互式地,您是否使用来自ssh pid is .. 消息的 pid 运行/usr/gnu/bin/kill?脚本是否同时退出?
  • @thatotherguy Perl 脚本仍在运行,因为该脚本派生了 ssh 进程,因此返回了终端。是的,这就是我正在使用的 pid。

标签: linux bash perl ssh


【解决方案1】:

即使是本地主机,ssh 也需要几十毫秒的时间来连接并执行命令。

当被脚本杀死时,ssh 会在启动后的几毫秒内死亡,因此它永远没有机会在远程主机上执行命令。

当被人杀死时,ssh 有几秒钟的时间来连接和执行。

换句话说,sleep 在第一种情况下不会死——它永远不会启动。

您可以通过让您的脚本在终止 ssh 之前等待一秒钟来确认这一点。

【讨论】:

  • 现在我在杀死之前插入了一个sleep 5,脚本现在输出Killed by signal 15.,但现在远程sleep 123也没有被杀死。所以你是对的 =) 但是为什么远程 sleep 123 能存活下来?
  • sleep 不在乎终端是否从其下方消失,并且 ssh shell 不是交互式的,因此在断开连接时它不会 SIGHUP 进程。
猜你喜欢
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多