私はこのコマンドを持っています:
cat somefile >file1 >file2
このコマンドを実行した後、なぜfile1
には何も含まれていません。最初のファイル(somefile
)の出力があるはずですが、その中には何もありません。
somefile
からの出力がコピーまたは書き込まれない理由を教えてください。 (file2
には出力が含まれますが、file1
には何も含まれません)
シェルリダイレクトの動作と実際の動作には違いがあると思います。
シェルの出力を複数回リダイレクトして、指定したすべての場所にリダイレクトされることを期待することはできません。代わりに、最後の場所(この場合はfile2
)にのみリダイレクトされます。カオスの答えは、そのようなI/Oリダイレクトがどのように機能するかについての適切な説明を提供します。
あなたが本当にやりたいことは:
$ cat example.txt | tee file1 > file2
tee
は、標準入力から読み取り、複数のファイル記述子に書き込むプログラムです。それらの1つはalways標準出力です。したがって、tee
を使用して出力をfile1
に書き込み、そのstdoutをfile2
にリダイレクトします。
また、コメントの提案に基づいて、これはあなたが探していることを行うためのより良い方法です:
$ tee file1 > file2 < example.txt
このアプローチには、パイプを介して読み取るのではなく、stdin
をリダイレクトするという利点があります。つまり、シェルは1つ少ないプロセスを生成する必要があります。また、「猫の無用」と呼ばれるものも排除します。
あなたがしたことは I/O-Redirection と呼ばれます。 >file
は、標準出力(stdout)を指定されたfile
にリダイレクトします。あなたの場合、あなたはそれを2回行いました。シェルは、同じ出力のリダイレクトを複数回処理しません。
この場合:
cat somefile >file1 >file2
シェルは、コマンド(cat somefile
)が実行される前にリダイレクトを処理します。つまり、ファイルのコンテンツを上書きするため、>
はファイルを長さゼロに切り捨てます。シェルがコマンドを実行する前に、ファイルは空でなければなりません。これは、両方の>
リダイレクトで行われます。
これで、シェルはリダイレクトを表示順に処理するため、2番目の(>file2
)が最初の(>file1
)をオーバーライドします。だから、最後のものは効果的に使われるものです。したがって、cat somefile
の出力はfile2
にリダイレクトされ、file1
は長さがゼロに切り捨てられます。
Stdoutを複数のプロセス/ファイルにリダイレクトするには、次のようにtee
を使用します。
cat somefile | tee file1 file2 file3 fileX
これは、内容を標準出力およびに、パラメーターとして指定されたすべてのファイルに出力します。