私は時々次のようなものを見ます:
cat file | wc | cat > file2
なぜこれを行うのですか?
結果(またはパフォーマンス)が単純に(有利に)異なるのはいつですか。
cat file | wc > file2
_cat file | wc | cat > file2
_
機能的には次のように機能するため、通常はcat
の2つの役に立たない使用法になります。
_< file wc > file2
_
ただし、以下の場合があります。
_cat file | wc -c
_
以上
_< file wc -c
_
これは、多くのwc
実装が通常のファイルに対して行う最適化を無効にすることです。
通常のファイルの場合、ファイルのコンテンツ全体を読み取らずに、ファイルのstat()
システムコールを実行して、iノードに格納されているサイズを取得するだけで、ファイルのバイト数を取得できます。
たとえば、次の理由により、ファイルを読み取ることができます。
stat()
情報は信頼できません(Linuxの_/proc
_または_/sys
_の一部のファイルなど):
_$ < /sys/class/net/lo/mtu wc -c
4096
$ cat /sys/class/net/lo/mtu | wc -c
6
_
もちろん、それらは例外です。一般的なケースでは、パフォーマンス上の理由から_< file wc -c
_を使用します。
これで、使用したいシナリオをさらに遠くまで想像できます:_cat file | wc | cat > file2
_:
wc
には、cat
が許可されている間は、ファイルへの読み取りまたは書き込みを禁止するapparmorプロファイルまたはその他のセキュリティメカニズムがあります(これは前代未聞でしょう)。cat
は(> 2のように)大きなものを扱うことができます32 バイト)ファイル。ただし、そのシステムではwc
ではありません(これまで、一部のシステムでは、一部のコマンドでこれが必要でした)。file2
_を開いていない場合でも、wc
(および最初のcat
)を実行してファイル全体を読み取る(そして最後の最後で強制終了する)必要があるかもしれません。書き込み。file
のコンテンツのオープンまたは読み取りの失敗(終了ステータス)を隠したい場合があります。 _wc < file > file2 || :
_の方が理にかなっていますが。lsof
からWordカウントを取得している、または_file2
_にWordカウントを保存しているという事実を(file
(開いているファイルのリスト)の出力から)非表示にしたい場合があります。 。これらの例は両方とも 猫の無駄な使用 です。どちらもwc < file1 > file2
と同等です。この例でcat
を使用する理由はありませんが、動的に出力を生成するものの一時的な代用としてcat file
を使用している場合を除きます。
私はそれが「猫の無用な使用」であると言うことについての議論に同意しませんが、canには理由があります:
多くの言語(英語を含む)では、単語と文は左から右に読み取られるため、同じ方法でデータの流れを示すと、読者にとってより自然に見えます。
2番目のcat
の理由は、戻りコードをマスクするためである可能性があります。といった:
$ wc < /etc/passw
sh: /etc/passw: Cannot find or open the file.
$ echo $?
1
cat
の場合:
$ wc < /etc/passw | cat
sh: /etc/passw: Cannot find or open the file.
$ echo $?
0
シェルにset -e
セットする。最初の例では、これはwc
の後にシェルを中止しますが、後者の例では続行します。これに対処する方法は他にもあります。
また、2つのステートメント(つまり、猫の有無にかかわらず)のパフォーマンスの違いはごくわずかであり(特に、今日のマシンでは)、それが重要である場合、Shellは不適切な言語です。
prog
が新しいサブプロセスをforkして終了し、新しいサブプロセスが標準出力に何かを書き込んでから終了するとします。
次に、コマンド
prog
サブプロセスが終了するのを待たず、シェルプロンプトが早く表示されます。しかし、コマンド
prog | cat
cat
の標準入力でEOFを待機します。これはサブプロセスが終了するのを効果的に待機します。したがって、これはcat
の便利な使用法です。