web-dev-qa-db-ja.com

コマンドラインユーティリティのファイル名としてstdoutを渡しますか?

出力を書き込むファイルの名前を渡す必要があるコマンドラインユーティリティを使用しています。

foo -o output.txt

stdoutに書き込むのは、正常に実行されたことを示すメッセージだけです。 output.txtに書き込まれたすべてを別のコマンドラインユーティリティにパイプできるようにしたいと思います。私の動機は、output.txtが最終的に保持する必要のない40 GBのファイルになることであり、大規模なファイルを段階的に操作するのではなく、ストリームをパイプ処理したいです。

このシナリオでは、実際の出力(つまりoutput.txt)を別のコマンドにパイプする方法はありますか?どういうわけか魔法のようにstdoutをファイル引数として渡すことができますか?

33
Jake

解決策1: プロセス置換 を使用する

これを行う最も便利な方法は、プロセス置換を使用することです。 bashでは、構文は次のようになります。

foo -o >(other_command)

(これは bashism であることに注意してください。他のシェルにも同様の解決策がありますが、最終的には移植性がないということです。)

解決策2: 名前付きパイプ を明示的に使用する

上記を明示的/手動で次のように実行できます。

  1. mkfifoコマンドを使用して名前付きパイプを作成します。

    mkfifo my_buf
    
  2. そのファイルを入力として他のコマンドを起動します

    other_command < my_buf
    
  3. fooを実行し、出力をmy_bufに書き込みます

    foo -o my_buf
    

解決策3:/dev/stdoutを使用する

次のように、デバイスファイル/dev/stdoutを使用することもできます。

foo -o /dev/stdout | other_command
38
aioobe

名前付きパイプは正常に動作しますが、bashプロセスの置換を介してより適切で直接的な構文を使用できるため、後で削除する必要がある永続的な名前付きパイプを使用しないという追加の利点があります(プロセスの置換では、舞台裏で一時的な名前付きパイプを使用します)。

foo -o >(other command)

また、出力をコマンドにパイプし、出力をファイルに保存する場合は、次のようにします。

foo -o >(tee output.txt) | other command

48
frankc

私の提案する解決策は必要な30文字以上ではなく18文字しかないため、stackoverflowを幸せにするために、十分に長い文を書きましょう。

foo -o /dev/stdout
31
Nestor Urquiza

UNIXの魔法を使って名前付きパイプを作成することができます:)

  1. パイプを作成する

    $ mknod -p mypipe
    
  2. パイプから読み取るプロセスを開始します

    $ second-process < mypipe
    
  3. パイプに書き込むプロセスを開始します

    $ foo -o mypipe
    
5
ktf

出力ファイル名として/ dev/ttyを使用します。何も出力しない場合は/ dev/nul /を使用するのと同じです。その後|これで完了です。

0
Jaime Garza