您好,我正在尝试记录用户从我的服务器所做的一切。我有一个脚本可以替代 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/