2009-03-20 42 views
0

私は、提供されたファイルの内容を取り出して処理し、結果をstdoutを通して画面に出力するバイナリプログラム*を持っています。オートメーションスクリプトでは、名前付きパイプを使用してデータをこのプログラムに送信し、出力を自分自身で処理したいと考えています。スクリプトを動作させようとすると、名前付きパイプからのデータを受け入れるバイナリプログラムに問題があることがわかりました。この問題を説明するために、私はUNIXシェルを使っていくつかのテストを概説しました。名前付きパイプの問題をどのように解決しますか?

  1. 実際のデータファイルを処理することによってプログラムが動作することを示すのは簡単です。

    $ binprog file.txt > output.txt 
    

    これにより、file.txtから処理された情報を含むoutput.txtが生成されます。

  2. 名前付きパイプ(pipe.txt)は、このデモンストレーションのとおり動作します。

    $ cat pipe.txt > output.txt 
    $ cat file.txt > pipe.txt 
    

    これにより、pipe.txtからのデータがパイプを介して送信された後にoutput.txtに格納されます。

  3. ファイルの代わりに名前付きパイプからバイナリプログラムを読み取っているとき、正常に動作しません。

    $ binprog pipe.txt > output.txt 
    $ cat file.txt > pipe.txt 
    

    この場合、catとbinprogが終了してもoutput.txtにはデータは含まれません。 topとpsを使って、私はbinprogが "走っている"のを見て、一見仕事をしています。すべてがエラーなしで実行されます。

この3番目の例では、binprogによって出力が生成されないのはなぜですか?

私はこれを動作させるために何かを試みることができますか?

[*]問題のプログラムは、libsvmからsvm-scaleです。私は、それらをきれいでシンプルに保つために例を一般化することを選んだ。

+0

名前付きパイプへの書き込みを開始する前にbinprogを起動すると、binprog read()が "file"(pipe.txt)を実行したときに、作動エラーコードに関係なく0バイトが出力される可能性があります、ちょうど終了します。 binprogの前にcatを実行したらどうなりますか? –

+0

Antti.huima、私は最初にパイプにデータをパイプし、その後にbinprogプロセスを開始しようとしましたが、違いはありません。まったく同じことが起こります。 – Nixuz

+0

バックグラウンドで 'cat pipe.txt> output.txt'を実行する必要はありませんか?同様に 'binprog'? –

答えて

1

binprogもstdinで入力を受け付けますか?もしそうなら、これはあなたのために働くかもしれません。

cat pipe.txt | binprog > output.txt 
cat file.txt > pipe.txt 

編集:簡単に言うには、SVM-規模のマンページをスキャンしました。代わりにこれを渦巻きにしてください:

cat pipe.txt | svm-scale - > output.txt 
+0

いいえstdinからの入力を受け付けません。 それは私のマニュアルページにはありませんでしたが、とにかく試してみましたが、うまくいきません。 – Nixuz

3

プログラムはパイプで動作しますか?入力ファイルへのランダムアクセスが必要な場合は、動作しません。プログラムは、入力ファイルを検索しようとするたびにエラーになります。

プログラムがパイプで動作するように設計されており、bashを使用している場合は、プロセス置換を使用して名前付きパイプを明示的に作成する必要がなくなります。

binprog <(cat file.txt) > output.txt 
+0

パイプで動作するはずですが、実行後もエラーは発生せず、クラッシュしません。代替案は面白いですが、最終的に私のスクリプトではうまくいかないでしょう。 – Nixuz

+0

端末でランダムアクセスがうまく動作しません。 –

0

binprogを入力として、端末以外でうまく動作しない場合は、多分あなたは、その入力のためにそれを(擬似)ターミナル(PTY)を与える必要があります。それは整理するのが難しいですが、expectプログラムはそれを比較的容易に行うための1つの方法です。 Wリチャード・スティーブンスとスティーブン・ア・ラゴの Advanced Programming in the Unix Environment, 3rd Ednと、Marc J RochkindのAdvanced Unix Programming, 2nd Ednのptyのプログラミングに関する議論があります。

他の何かは、trussまたはstraceまたはそれに相当するものの出力です。これらのプログラムは、プロセスによって行われたすべてのシステムコールを記録します。 Solarisでは、次のコマンドを実行します。

truss -o binprog.truss binprog 

対話形式で実行します。それから私は、私は/リダイレクトでそれを試してみて、その後、名前付きパイプからの私は/リダイレクトで、それが何をしているのかには大きな違いがあるかもしれませんし、システムコールがぶら下がっているのを見るかもしれません。トラスログファイルにフォークが含まれている場合は、子どもをフォローするには '-f'フラグを追加する必要があります。

関連する問題