我在Windows上运行以下代码段.从客户端读取后,服务器开始连续监听.我希望在一段时间后终止此命令.
如果我使用报警()内的函数调用main.pl,那么它会终止整个Perl程序(在这里main.pl),所以我称此系统通过将其放置在一个单独的Perl文件并调用这个Perl的文件(命令alarm.pl使用),在原有的Perl文件系统命令.
但是通过这种方式,我无法system()在原始Perl文件中或在被调用的Perl文件中获取此调用的输出.
有人可以让我知道终止system()呼叫的方式或以我上面使用的方式获取输出吗?
my @output = system("alarm.pl");
print"one iperf completed\n";
open FILE, ">display.txt" or die $!;
print FILE @output_1;
close FILE;
Run Code Online (Sandbox Code Playgroud)
alarm 30;
my @output_1 = readpipe("adb shell cd /data/app; ./iperf -u -s -p 5001");
open FILE, ">display.txt" or die $!;
print FILE @output_1;
close FILE;
Run Code Online (Sandbox Code Playgroud)
两种方式display.txt总是空的.
bri*_*foy 15
这里有一些单独的问题.
首先,为了防止警报死亡,您需要处理ALRM信号.请参阅警报文档.您不应该需要两个脚本.
其次,系统不捕获输出.如果你想这样做,你需要一个反引号变体或管道.Stackoverflow上已经有了答案.
第三,如果alarm.pl将任何内容放入display.txt中,则在写入模式下重新打开文件时,会在main.pl中将其丢弃.您只需要在一个地方创建文件.当你摆脱额外的脚本,你不会有这个问题.
我最近有一些问题alarm和system,但切换到IPC ::系统::简单固定的.
祝好运, :)
我到底在想什么?您不需要此任务的后台进程.您只需要按照perldoc -f alarm函数中的示例进行操作,并将时间敏感的代码包装在一个eval块中.
my $command = "adb shell cd /data/app; ./iperf -u -s -p 5001";
my @output;
eval {
local $SIG{ALRM} = sub { die "Timeout\n" };
alarm 30;
@output = `$command`;
alarm 0;
};
if ($@) {
warn "$command timed out.\n";
} else {
print "$command successful. Output was:\n", @output;
}
Run Code Online (Sandbox Code Playgroud)
在eval块中,您可以以常规方式捕获输出(使用反引号或qx()或readpipe).虽然如果通话超时,则不会有任何输出.
如果你不需要输出(或者不介意一起黑客攻击一些进程间通信),那么几乎可以防止出现警报并system在子进程中运行调用.
$command = "adb shell cd /data/app; ./iperf -u -s -p 5001";
if (($pid = fork()) == 0) {
# child process
$SIG{ALRM} = sub { die "Timeout\n" }; # handling SIGALRM in child is optional
alarm 30;
my $c = system($command);
alarm 0;
exit $c >> 8; # if you want to capture the exit status
}
# parent
waitpid $pid, 0;
Run Code Online (Sandbox Code Playgroud)
waitpid当孩子的system命令结束或孩子的闹钟响起并杀死孩子时,它将返回.$?如果您的SIGALRM处理程序调用,将保存系统调用的退出代码或其他内容(在我的系统上为142)表示未处理的SIGALRM或255 die.