2

以下の質問をしたところ、非常に近い答えが見つかりましたが、後でそれが機能しないことに気付きました。私はperlでパイプを使用しています。しかし、パイプを介して条件に到達する前に、関数の実行が完了します。10本のバナナが通過したらプロセスを停止するために、実行時に正確な秒でチェックする方法はありますか

出力を解析し、文字列が出現する回数をカウントする

こんにちは、私はこれを試しました...しかし、うまくいきません...プロセスは、停止する機会を得る前に終了しています。pidでプロセスの流れを実際に制御できるものはありませんか。つまり、10 本のバナナが終わったことに気付く前に、23 本のバナナが交差しました。パイプの流れは実際のプロセスよりも遅いと推測しています

私がやりたいのは、すでに実行中のプロセスに遅延を追加することだけです。コマンド 1 アウト コマンド 2 アウト バナナ これで、バナナを解析して、プロセスに 5 秒の遅延を設定できます。遅延を挿入すると、その時間内に perl スクリプトを実行し、時間内にスクリプトを停止できます。

私の質問を明確にするために:私が書いたコード:

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

だから私は最後の2つの値を望まず、プログラムを停止させたい. commandA は次のとおりです。

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

重要な編集: 私が目指しているのは、デバッガーの作成です。誰かが、オープン ソース デバッガーまたはプロセスを制御するその他のコードを持っています。

4

2 に答える 2

1

あなたがやろうとしていることは決して確実に動作しません.commandAファイルにデータを書き込んでいるプロセスと、それを強制終了しようとしている他のプロセスとの間には常に競合があります. 2 つのプロセス間にいくつかのバッファリング ステージがあるため、書き込みプロセスが強制終了される前に、余分な出力を大量に生成する可能性が非常に高くなります。

これを回避するために私が考えることができる唯一の方法は次のとおりです。

  1. 終了条件チェック (10 個の「バナナ」を出力したら停止) を、出力を生成しているプログラムに移動します。そうすれば、それを殺す必要はまったくありません。

  2. 各行を印刷した後、出力を生成するプログラムに、他のプログラムからの何らかの確認を待機させます。これは可能ですが、ややこしく、おそらく非効率的です。

  3. を使用する代わりにtee、次のように、制御プログラム (終了条件をチェックするプログラム) にデータを出力ファイルに書き込みます。

    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;
    
于 2013-07-19T19:33:22.063 に答える