如何使用 'system()' 终止在 perl 脚本中启动的命令
how to terminate a command that has started in a perl script, using 'system()'
我已经编写了一个 Perl 脚本来 运行 通过脚本给定的一些命令。
system("my_command");
运行安装我的 Perl 脚本后,“my_command”在 Linux 终端上正常启动。后来,我使用 'ctrl+z; kill %%' 杀死了我的脚本。但是“my_command”仍然是 运行ning。我再次尝试 'kill %%' 几次,但“my_command”没有终止。
(“my_command”是另一个正常工作的 Perl 脚本)。
我需要的是,如果我终止初始 Perl script/runner,那么所有使用 'system()' 启动的命令都应该终止。
有什么办法可以实现吗?
system
对此用处不大。考虑使用 open2
,其中 returns 已启动子进程的进程标识符。
use IPC::Open2;
# A system() like call using open2():
my $pid = open2('>&STDOUT', '<&STDIN', @CommandLine);
您现在可以在 $pid
上 kill
和 waitpid
。
这是一个使用一些老式 OOP 的示例,这样当您的程序退出时,您启动的所有进程都会自动 kill
ed。我确信已经有现成的 perl 包以更完整的方式封装了它,但这应该给你一个大概的想法。
#!/usr/bin/perl
use strict;
use warnings;
package mysystem;
use IPC::Open2;
sub new {
my $class=shift;
bless {
'pid' => open2('>&STDOUT', '<&STDIN', @_)
}, $class;
}
sub DESTROY {
my $self = shift;
$self->kill(15); # or whatever signal you want to send to it
$self->wait;
print "DEBUG PRINTOUT: DONE\n";
}
sub wait {
# wait for the process to terminate
my $self = shift;
waitpid($self->{pid}, 0);
}
sub kill {
# send a signal to the process
my ($self, $signal) = @_;
kill($signal, $self->{pid});
}
sub alive {
# check if the process is alive
my $self = shift;
$self->kill(0) == 1;
}
sub run {
# do like system(), start a sub process and wait for it
my $sys = new(@_);
$sys->wait;
}
package main;
sub handler {
print "Caught signal @_ - exiting\n";
exit(0);
}
$SIG{INT} = \&handler;
my $proc = mysystem->new('sleep', '1000');
print "Pid ". $proc->{pid} . " is " . ($proc->alive()?"alive":"dead") . "\n";
print "Letting the destructor kill it\n";
可能的输出:
Pid 3833402 is alive
Letting the destructor kill it
DEBUG PRINTOUT: DONE
我已经编写了一个 Perl 脚本来 运行 通过脚本给定的一些命令。
system("my_command");
运行安装我的 Perl 脚本后,“my_command”在 Linux 终端上正常启动。后来,我使用 'ctrl+z; kill %%' 杀死了我的脚本。但是“my_command”仍然是 运行ning。我再次尝试 'kill %%' 几次,但“my_command”没有终止。 (“my_command”是另一个正常工作的 Perl 脚本)。
我需要的是,如果我终止初始 Perl script/runner,那么所有使用 'system()' 启动的命令都应该终止。
有什么办法可以实现吗?
system
对此用处不大。考虑使用 open2
,其中 returns 已启动子进程的进程标识符。
use IPC::Open2;
# A system() like call using open2():
my $pid = open2('>&STDOUT', '<&STDIN', @CommandLine);
您现在可以在 $pid
上 kill
和 waitpid
。
这是一个使用一些老式 OOP 的示例,这样当您的程序退出时,您启动的所有进程都会自动 kill
ed。我确信已经有现成的 perl 包以更完整的方式封装了它,但这应该给你一个大概的想法。
#!/usr/bin/perl
use strict;
use warnings;
package mysystem;
use IPC::Open2;
sub new {
my $class=shift;
bless {
'pid' => open2('>&STDOUT', '<&STDIN', @_)
}, $class;
}
sub DESTROY {
my $self = shift;
$self->kill(15); # or whatever signal you want to send to it
$self->wait;
print "DEBUG PRINTOUT: DONE\n";
}
sub wait {
# wait for the process to terminate
my $self = shift;
waitpid($self->{pid}, 0);
}
sub kill {
# send a signal to the process
my ($self, $signal) = @_;
kill($signal, $self->{pid});
}
sub alive {
# check if the process is alive
my $self = shift;
$self->kill(0) == 1;
}
sub run {
# do like system(), start a sub process and wait for it
my $sys = new(@_);
$sys->wait;
}
package main;
sub handler {
print "Caught signal @_ - exiting\n";
exit(0);
}
$SIG{INT} = \&handler;
my $proc = mysystem->new('sleep', '1000');
print "Pid ". $proc->{pid} . " is " . ($proc->alive()?"alive":"dead") . "\n";
print "Letting the destructor kill it\n";
可能的输出:
Pid 3833402 is alive
Letting the destructor kill it
DEBUG PRINTOUT: DONE