Perl fork exec,父系统中的系统并杀死子系统

标签 perl ssh exec fork kill

您好,我正在尝试记录用户从我的服务器所做的一切。我有一个脚本可以替代 ssh 并记录所有内容。

问题是当用户停止 ssh session 时,记录操作的子进程不会被终止。

my $pid = fork();
die "unable to fork: $!" unless defined($pid);
if (!$pid) {  # child
    exec("tail -f $logfile | logger -t $ENV{SUDO_USER}:$target ");
    die "unable to exec: $!";
}

$show_cmd && print "% $cmd\n" ;
system $cmd or die "exec() failed: $!\n" ;
printf "Session end pid to kill %d\n", $pid;
kill 1, $pid;
waitpid $pid, 0;
printf "End of the script.\n";

我也放了

$SIG{CHLD} = "IGNORE";

如果我删除了指令系统(启动用户原始 ssh 命令的指令),子进程就会被杀死,但这也会使我的脚本变得毫无用处。

有什么想法可以成功终止进程吗?

编辑: 当系统命令结束时,脚本继续,执行 printf,并打印子进程的 pid。

编辑2:

这是 ssh session 期间的“ps 虚假”

root      4976  [...]   \_ /usr/bin/perl -w /usr/bin/ssh **.**.**.62
root      4977  [...]      \_ sh -c tail -f /var/log/log-session/2014-11-26.155910.*******:root@**.**.**.62 | logger -t *********:root@**.**.**.62
root      4979  [...]      |   \_ tail -f /var/log/log-session/2014-11-26.155910.*********:root@**.**.**.62
root      4980  [...]      |   \_ logger -t ********:root@**.**.**.62
root      4978  [...]      \_ sh -c /usr/bin/realssh -o UserKnownHostsFile=/etc/ssh/known_hosts_Securite -i /etc/ssh/id_dsa_Securite **.**.**.62 | ...
root      4981  [...]         \_ /usr/bin/realssh -o UserKnownHostsFile=/etc/ssh/known_hosts_Securite -i /etc/ssh/id_dsa_Securite **.**.**.62
root      4982  [...]         \_ /usr/bin/tee -a /var/log/log-session/2014-11-26.155910.********:root@**.**.**.62

session 结束时:^D 来自用户

Connection to **.**.**.62 closed.
Session end pid to kill: 4977
End of the script.

以及“ps faux”的结果:

 root      4979  [...]        tail -f /var/log/log-session/2014-11-26.155910.*********:root@**.**.**.62
 root      4980  [...]        logger -t ********:root@**.**.**.62

所以最后这两个进程仍然没有附加任何东西。

最佳答案

我认为问题是杀死所有进程树并且 That SO answer solves the problem

我把这个交给了子进程

setpgrp(0, 0);

并将kill指令更改为

kill 9, -$pid;

现在看起来像这样

my $pid = fork();
die "unable to fork: $!" unless defined($pid);
if (!$pid) {  # child
    setpgrp(0, 0);
    exec("tail -f $logfile | logger -t $ENV{SUDO_USER}:$target ");
    die "unable to exec: $!";
}

$show_cmd && print "% $cmd\n" ;
system $cmd or die "exec() failed: $!\n" ;
printf "Session end pid to kill %d\n", $pid;
kill 9, -$pid;
waitpid $pid, 0;
printf "End of the script.\n";

谢谢你帮助我

关于Perl fork exec,父系统中的系统并杀死子系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27145798/

相关文章:

git - 小型开发团队需要多少个 github ssh key ?

ssh - 如果 SSH session 断开连接,通过 SSH 在 Vmware ESXI 主机外壳上运行的进程是否会继续?

linux - 无法让 linux 'exec' 命令正常工作

perl - 传递函数对象并调用它

perl - 如何使用 'subroutine reference' 作为哈希键

arrays - 如何在Perl中访问哈希数组?

java - Hadoop伪分布式: SSH command

C: exec binary without main with exec*() 系统调用

PHP 批处理

perl - perl read() 函数和不是 ref 的缓冲区背后的魔法是什么?