停止一个具有perl条件的进程 [英] stop a process with a condition in perl

查看:143
本文介绍了停止一个具有perl条件的进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我问下面的问题,我发现一个非常接近的答案,但后来意识到它不起作用。我在perl中使用管道。但是在我甚至通过管道碰到我的状况之前,该功能已完成运行。有一种方法可以在运行时非常精确地检查一下,一旦10个香蕉的通行证就会停止进程。



解析输出和计数字符串出现的次数



你好,我尝试过这个...但是它不起作用...这个过程在我有机会停止之前已经完成了。没有什么可以实际控制进程的流程与pid。我的意思是,23只香蕉已经越过,发现10只已经完成了。我猜测管道流量比实际流程慢[



我想做的是在已经运行的进程中添加一个延迟。喜欢:
让我们知道输出将如下所示:
command 1 out
command 2 out
banana
现在我可以解析香蕉并拖延在此过程中5秒钟。一旦我注入了一个延迟,我可以在那段时间运行我的Perl脚本,并及时停止脚本。



让我的问题清楚:
的代码我写道:

 我的$ pid =打开我的$ pipe,' -  |','commandA | tee banana.foo'
or die错误打开管道从commandA:$!\\\
;
#打开我的$ pipe,'commandA |发球台结果|'
#或死错误打开管道从commandA:$!\\\
;
print$ pid\\\
;
我的$ n = 0;
while(< $ pipe>){
$ n ++ if / banana /;
last if $ n> 0;
打印pipestring\\\
;
}
kill'INT',$ pid;
关闭$ pipe;如果还没有完成,则用SIGPIPE杀死命令

if($ n eq 1){

printcommandA打印banana'\\\
;
}
else
{
打印没有发生过
}

banana.foo(实际结果)| banana.foo(预期结果)
one |一个
两个|两个
三|三
香蕉|香蕉


所以我不想要最后2个值并希望程序停止。
commandA是:

  echo one 
echo two
echo three
echo香蕉
回音四
回音五

重要编辑:我想我会正在创建一个调试器。有人拥有任何开放源代码调试器的代码或其他控制进程的代码。

解决方案

工作可靠:在$ code> commandA 之间总是有一个比赛,将数据写入文件,另一个进程试图将其杀死。由于两个进程之间有几个缓冲阶段,因此写入过程很有可能在被杀之前产生大量额外的输出。



唯一的我可以想到的方法是:


  1. 移动终止条件检查(打印10个香蕉后停止)到产生输出的程序。


  2. 产生输出的程序在打印后等待其他程序的某种确认每行。


  3. 而不是使用 tee ,具有控制权程序(检查终止条件的)将数据写入输出文件,如下所示:

     打开我的$ ,'> banana.foo'
    或死打开banana.foo写错误:$!\\\
    ;

    我的$ pid =打开我的$管道,'commandA |'
    或死错误打开管道从commandA:$!\\\
    ;

    我的$ n = 0;
    while(< $ pipe>){
    print $ out $ _;
    $ n ++ if / banana /;
    last if $ n> 0;
    }
    kill'INT',$ pid;
    关闭$ pipe;



I asked the following question below and I found a very close answer but later realised it doesn't work. I am using pipe in perl. But before I even hit my condition through the pipe, the function is completed its run. Is there a way to check at run-time at the very exact second to stop the process once 10 banana's pass

parse output and count number of times a string appears

Hello I tried this...but it doesn't work...the process is finished way before I even get the chance to stop it. Isn't there anything which can actually control the flow of process with the pid. I mean, 23 banana's had crossed before it found that 10 were done. I am guessing pipe flows slower than the actual process

All I want to do is add a delay in the already running process. Like: lets say we know what the output will look like: command 1 out command 2 out banana Now I can parse for banana and put a delay of 5 seconds in the process. Once I inject a delay, I could run my perl script in that time and stop the script in time.

To make my question clear: the code I wrote:

my $pid = open my $pipe, '-|', 'commandA | tee banana.foo'
     or die "Error opening pipe from commandA: $!\n";
#  open my $pipe, 'commandA | tee result |'
#    or die "Error opening pipe from commandA: $!\n";
  print "$pid\n";
  my $n = 0;
  while (<$pipe>) {
    $n++ if /banana/;
    last if $n > 0;
    print "pipestring\n";
  }
  kill 'INT', $pid;
  close $pipe;  # kills the command with SIGPIPE if it's not done yet

  if ($n eq 1)  {

  print "commandA printed 'banana'\n";
  }
  else
  {
    print "nothing happened\n";
  }

banana.foo ( actual result )   |  banana.foo (expected result)
one                            |  one
two                            |  two 
three                          |  three 
banana                         |  banana
four
five

So I don't want the last 2 values and want the program to stop. commandA is :

echo one
echo two
echo three
echo banana
echo four
echo five

IMPORTANT EDIT: I think what I would be going towards is creating a debugger. Someone has the code for any open source debugger or something else which controls processes.

解决方案

What you're trying to do will never work reliably: there's always a race between the commandA process writing data to the file and the other process trying to kill it. Since there are several buffering stages between the two processes, it's quite likely that the writing process will have a chance to produce a lot of extra output before it's killed.

The only ways I can think of to avoid this are:

  1. Move the terminating condition check (stop after printing 10 "banana"s) to the program that is producing the output. That way, you won't need to kill it at all.

  2. Have the program producing the output wait for some kind of confirmation from the other program after printing each line. This is possible, but rather tricky and probably inefficient.

  3. Instead of using tee, have the controlling program (the one that checks for the terminating condition) write the data to the output file, like this:

    open my $out, '> banana.foo'
         or die "Error opening banana.foo for writing: $!\n";
    
    my $pid = open my $pipe, 'commandA |'
         or die "Error opening pipe from commandA: $!\n";
    
    my $n = 0;
    while (<$pipe>) {
        print $out $_;
        $n++ if /banana/;
        last if $n > 0;
    }
    kill 'INT', $pid;
    close $pipe;
    

这篇关于停止一个具有perl条件的进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆