パイプをopenして/usr/bin/grepを実行する方法

このQ&Aのポイント
  • 子プロセスでopenして標準出力から/usr/bin/grepの実行結果を取得する方法を知りたい
  • open関数の戻り値で子プロセスが起動しているかどうかを判断し、起動している場合にはgrepを実行する
  • /usr/bin/grepの第二引数に何を指定するべきか迷っている
回答を見る
  • ベストアンサー

パイプをopenして/usr/bin/grepを実行する方法

子プロセスで"-|"でopenして、そこに標準出力で/usr/bin/grepの実行結果を出力し、そのデータを取得したいです。 $pid = open(FIFO, "-|")をした時点で、$pidにはプロセスIDが入っています(0以外)。 0のときは子プロセスが起動しているのでgrepを実行し、0以外であれば標準出力の内容を取得するというロジックでいいと考えたのですが、一度もgrepが実行されません。 また、grepをexecしているのですが、その第二引数を何にしていいのかも模索中です。 どこをどのように修正したらいいでしょうか。 よろしくお願いします。 die "openエラー: $!" unless defined ($pid = open(FIFO, "-|")); if(!$pid) { exec('/usr/bin/grep', '-isl', $search, @list) or die "grepエラー: $!"; } else { while (<FIFO>) { print $_; } close FIFO; } 【環境】 WindowsXP Professional(SP2) Apache2.2 ActivePerl v5.8.8

  • cieux
  • お礼率90% (63/70)
  • Perl
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

質問の例では双方向のやり取りは必要ないので、 #1の tacosan さんの回答の通りで open my $fd, "grep -isl '$search' @list"or die $!; とでもすればよいのではないかと。 ついでにいうと、このパターンの場合、Unixのような fork & exec が必要なので、ActivePerlでは 期待通りに動きません。 というかopenのところで '-' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。 となると思うんですが。 ついでのついでで、三引数バージョンの open ならActivePerlでもいけます。 open my $fifo, "-|", 'grep -e use *.pl' or die; #open(my $fifo, '-|') || exec 'grep', '-e', 'use', '*.pl'; #↑こっちはダメ while (<$fifo>) { print; } もし Perlの標準出力からデータを送る→ プログラムで処理してその標準出力に送る→ Perlで受け取る ということをやりたいのなら、 IPC::open2 とか IPC::open3 とかつかってください。

cieux
質問者

お礼

ご回答ありがとうございます。 画面で操作して結果を見ているので、openのエラーをうまく拾えていないのかもしれません。そこはログを見てみようと思います。 最終的にはUnix上で動かすので、そのあたりも加味して、IPC::open2、IPC::open3も含めもう一度見直してみようと思います。

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

事情はわからないんですけど, open で直接 grep してはいけないんでしょうか?

cieux
質問者

お礼

回答ありがとうございます。 できるだけ元のソースを活かそうと思ったので、このようになっています。 状況としては、直接grepしても問題ないと思います(が、自信ありません…)。

関連するQ&A

  • /usr/loca/binに実行ファイルをコピーし

    Linux(cygwin)の環境で /usr/srcでビルドして作った実行ファイルを パスを通した/usr/local/binにコピー(cp -a)して実行するとなぜか出力は何も出ず終了し、 コピー元の/usr/src以下の実行ファイルをフルパスを指定して実行した場合のみ 正しく実行されますがこれはなぜでしょう? 具体的には /usr/srcでビルドしたbinutilsのas-newなどを #cp -a /usr/src/binutils/as-new /usr/local/bin/as-copy したときに test.sがあるホームディレクトリで #as-copy test.s #→何も表示されず実行終了。 #/usr/src/binutils/as-new test.s →a.outが出力されます。(正常に実行)

  • my $pid = open PIPE, "-|";の後の挙動

    CGIプログラミング第2版 233ページに掲載されているコードがうまく動きません。 my $pid = open PIPE, "-|"; die "$をforkできません!" unless defined $pid; unless ( $pid ) { exec FIGLET, $string or die "figletへのパイプを開けません: $!"; } このコードは入力した文字列をアスキーアートにしてくれるものなのですが、どうも最後のfigletの行が実行されていないようなのです。 openの使い方が特殊らしく、少ない行数の割に、えらい複雑なコードだな~と感じています。 openを実行した時にフォークが発生し、最終的に子プロセスがfigletを実行してくれるはずなのですが、どうも子プロセスがいない感じがします。 例えば fork; print(0); こんな感じにフォークをした場合 00 のように0が2個出力されるのですが、 この例題のopenの直後に print(0); と記述しても 0は1個しか出力されませんでした。 子プロセスはどこへ行ってしまったのでしょうか。 この例題は私の理解力では意味不明です。 誰か分かりやすく教えてください~~

    • ベストアンサー
    • Perl
  • Perlを実行する方法

    Perlを実行するために <?php $ret = exec('/usr/bin/php /usr/local/apache/public_html1/testdir/a.cgi'); print $ret; ?> のように書きましたが、a.cgiは実行されないし$retは空白でした。 execでなくてもよいのですが、普通はPHPの実行中に、ある処理をさせるa.cgiを実行させるにはどうしているんでしょうか? a.cgiの処理が終わるまでphpのprint $ret;のステートメントの実行は待ち状態で、a.cgiの処理結果がTRUEなのかFALSEなのかを得られればさらによいです。

    • 締切済み
    • PHP
  • プロセスが実行中かどうか調べる方法

    CreateProcessで作ったプロセスが実行中かどうか調べる方法はありませんか。 標準出力に値を吐き出し続けるコンソールアプリケーションから、値を取得して処理をしたいのですが、CreateProcessでつくってパイプで処理しようとしています。ぐぐったところWaitForSingleObjectで待つようなサンプルは見つかったのですが、呼び出したプロセスが終了しないのでこれは使えないので 実行中はずっとループし続けるような感じにしたいのですが。 よろしくお願いします

  • DNSのcronデーモンが停止してしまう

    みなさん、こんにちは。 タイトルの質問です。 solarisでDNSサーバとメールサーバを兼用しています。 そのサーバでなぜかcrondがストップしてしましました。 # tail -10 /var/cron/olog ! ******* CRON ABORTED ******** (月) 1月 27 20:46:13 2003 ps -ef | grep cron で cron のプロセス(/usr/sbin/cron)が存在していません。 messages, syslog, dmesg には、 cronに関連したメッセージはありませんでした。 # /etc/rc2.d/S75cron start でもたちあがりません。 # cd /etc/rc3.d # sh -x ./S75cron start + /usr/bin/ps -e + /usr/bin/grep cron + /usr/bin/sed -e s/^ *// -e s/ .*// pid= + [ = ] + /usr/bin/rm -f /etc/cron.d/FIFO + [ -x /usr/sbin/cron ] + /usr/sbin/cron # ps -ef | grep cron root 21364 1 0 23:46:15 ? 0:00 /usr/sbin/cron で立ち上がりました。 外部からの侵入形跡はなく、どうしてクーロンが停止したのか 理由が分かりません。 どなたかお分かりになる方、教えてください。 宜しくお願い致します。

  • 仮想フレームバッファXvfb上でfirefoxを実行したいが、 Gtk-WARNING **: cannot open display: となる

    .shから php test.php とし、以下のスクリプトをroot権限としてcrontab経由で実行しています。 <?php $CapAddr = 'http://google.com'; system('firefox -display :1 -remote "openurl(' . $CapAddr . '), new-window"'); ?> ところが、ssh接続したターミナル上でimportコマンドで画面のキャプチャを取得して開いてみると 指定したページが表示されていません。吐いているエラーを見ると、 (firefox-bin:6340): Gtk-WARNING **: cannot open display: となり、実行に失敗しています。 ssh接続した所で直に打ち込めば何ら問題なく言うことを聞いてくれるのですが、 shell script上で php /home/htdocs/WebPageCapture.php とするとまたしても同じエラーを吐きます。 次はやり方を変えて、呼び出さずに直接CLI版のPHPを動かす方法を試しました。 #!/usr/bin/php <?php で始まる、同一のコードです。 すると再び、同じ (firefox-bin:7802): Gtk-WARNING **: cannot open display: のエラーが発生してます。 terminalで同じ事をすると上手く行くだけに困っています。 お力を貸していただけませんでしょうか、よろしくお願いいたします 接続元:Mac OSX Tiger 接続先サーバ環境:CentOS4.2 # ps ax | grep Xvfb /usr/X11R6/bin/Xvfb :1 -screen 0 1024x2048x24

  • Apacheの再起動エラーについて

    Apacheの再起動時ですが、プロセス?の関係でしょうか。 以下の様なエラーになり、ブラウザからアクセスできませんん。 どうやって治すのでしょうか? /usr/local/bin/apachectl stop: httpsd (no pid file) not running Apache will not die, restart failed"

  • grep でパラレル検索するには

    あるディレクトリいかに置かれているソースコードの中で特定のパターン (文字列) を含むファイルの一覧を取得するのに grep を使って検索してい るのですが、もう少しよい方法がないかと試行錯誤しています。 [現行法] find . -type f | \ while read line; grep -qP pattern "$line" && echo $line; done そこで、使用しているサーバのCPU 数が8であることに目を付け、マルチ プロセスもしくはマルチスレッドの仕組みを用いて8多重でgrepを実行で きる仕組みを考えています。 最初に考えたのは以下のような方法です。 ・pthread を利用する。 ・各レッドで system 関数を使用して grep を実行する。 ・子プロセスは標準入力をパイプから受け取るようにする。 ・検索対象となるファイル一覧の読み込みは mutex を用いて制御する。 →system 関数はシェル経由で grep をコールするようで、オーバーヘッド が気になるなどの理由により却下。 次に考えたのは以下のような方法です。 ・pthread を利用する。 ・各スレッドで fork し、子プロセスで grep を実行する (exec)。 ・子プロセスは標準入力をパイプから受け取るようにする。 ・検索対象となるファイル一覧の読み込みは mutex を用いて制御する。 →デッドロックの問題が解決できずに断念。 pthread で fork を使う場合は直ぐに exec するようにしないとデッド ロックする可能性があるという記事をネット上で見つけました (標準入力 をパイプから受け取るようにする処理があるため直ぐには exec できな い)。で、実際にもそのようになってしまいました。 そして、最終的に考えているのが以下のような方法です。 ・fork を利用する。 ・各プロセスでさらに fork し、孫プロセスで grep を実行する (exec)。 ・孫プロセスは標準入力をパイプから受け取るようにする。 ・検索対象となるファイル一覧の読み込みはセマフォを用いて制御する。 でも、本当にこのようにマルチプロセス+セマフォを使う方法でしか 「grep でパラレル検索」を実現することはできないのでしょうか? pthread で実現することには失敗してしまいましたが、もう少し改良して 成功できないかと考えているのですが・・・。 (かと言って、あちこち mutex でロックしてしまうと、せっかくのスレッ ドが生かされない?)

  • リダイレクトで空ファイルを生成しない方法

    以下のようにcronの実行結果にgrepをかけて、出力をファイルに書き出しているのですが、grepの結果出力がないときにサイズ0のファイルが生成されます。 cron.php | grep -v '\[ OK \]\|#!/usr/bin/php' > log/`date +%Y%m%d`cron.log 出力があるとき以外ファイルを生成させない方法はありますか? 宜しくお願い致します。

  • ファイルの入出力が出来ません。

    perlの初心者です。 cgiを作ろうとしています。 標準出力には出力できても、ファイルの入出力が出来ません。 #!/usr/bin/perl open(OUT,">>test"); print OUT "test data"; close (OUT); と実行しても、エラーもでないのですが、ファイルも作られず、書き込みもされません。 しかし、コマンド名'test'としてセーブして、プロンプトから'perl test'とするとファイルに書き込みされるようです。 perlの設定の問題なのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Perl

専門家に質問してみよう