シェルが「猫の無駄な使用」を自動的に修正しないのはなぜですか?[閉まっている]


28

多くの人々は、ラインに沿ってコードを含むonelinersとスクリプトを使用します

cat "$MYFILE" | command1 | command2 > "$OUTPUT"

cat技術的には/usr/bin/cat、コマンドが実行された場合にこれを回避できる新しいプロセス(多くの場合)を開始する必要があるため、最初は「catの無駄な使用」と呼ばれます。

< "$MYFILE" command1 | command2 > "$OUTPUT"

シェルは起動するcommand1だけでstdin、指定されたファイルをポイントするだけです。

シェルがこの変換を自動的に行わないのはなぜですか?「猫の無用な使用」構文は読みやすく、無用な猫を自動的に取り除くのに十分な情報がシェルにあるはずです。catシェルはパスにバイナリを使用する内部代わりに、それを実装することができなければならないので、POSIX規格で定義されています。シェルには、1つの引数バージョンのみの実装と、パス内のバイナリへのフォールバックさえ含めることができます。


22
これらのコマンドは実際には同等ではありません。1つはstdinがファイルであり、もう1つはパイプであるため、厳密に安全な変換ではないためです。ただし、それを行うシステムを作成できます。
マイケルホーマー

14
ユースケースを想像できないということは、アプリケーションが指定された動作に無用に依存することを許可されないという意味ではありません。以下からのエラーの取得lseekなど、まだ動作が定義され、異なる結果を引き起こす可能性が、異なるブロッキング動作は意味的に意味のあることができ、あなたが知っていた場合には、変更を行うことが許容だろうのコマンドであったと、彼らは気にしませんでした知っていました、または、そのレベルで互換性を気にしなかったが、その利点はかなり小さい場合。私は、利益の欠如が適合コストよりも状況を促進すると想像しています。
マイケルホーマー

3
catただし、シェルは、それ自体または他のユーティリティを絶対に実装できます。また、システムに属する他のユーティリティがどのように機能するかを知ることができます(たとえば、システムに付属する外部grep実装がどのように動作するかを知ることができます)。これは完全に実行可能ですので、なぜ実行しないのか不思議に思うでしょう。
マイケルホーマー

6
@MichaelHomer たとえば、システムに付属の外部grep実装がどのように動作するかを知ることができるため 、シェルはの動作に依存するようになりましたgrep。そしてsed。そしてawk。そしてdu。そして、他の何千ものユーティリティではないにしても、何百ものユーティリティですか?
アンドリューヘンレ

19
私のコマンドを編集するのは私のシェルのかなりクールではないでしょう。
アゾールアハイ

回答:


25

2つのコマンドは同等ではありません。エラー処理を検討してください。

cat <file that doesn't exist> | less パイプされたプログラムに渡される空のストリームを生成します...そのようなものとして、何も表示されない状態になります。

< <file that doesn't exist> less バーを開くことに失敗し、その後、まったく開きません。

前者を後者に変更しようとすると、潜在的に空白の入力でプログラムを実行することを期待しているスクリプトをいくつでも壊す可能性があります。


1
これが両方の構文の最も重要な違いだと思うので、あなたの応答を受け入れられたものとしてマークします。があるバリアントcatはパイプラインの2番目のコマンドを常に実行しますが、入力リダイレクトだけのバリアントは入力ファイルが欠落している場合はコマンドをまったく実行しません。
ミッコランタライネン

ただし、これは実行<"missing-file" grep foo | echo 2されませんgrepが実行されechoます。
ミッコランタライネン

51

「役に立たないcat」は、スクリプトを実行するときに実際に実行されるものよりも、コードの記述方法に関するものです。これは一種のデザインのアンチパターンであり、おそらくより効率的な方法で実行できることを行う方法です。特定のツールを最適に組み合わせて新しいツールを作成する方法を理解するのは失敗です。パイプラインでいくつsedかのawkコマンドやコマンドをつなげることも、この同じアンチパターンの症状であると言うことができると主張します。

catスクリプト内の「無駄な使用」のインスタンスを修正することは、主にスクリプトのソースコードを手動で修正することです。ShellCheckなどのツールは、明らかなケースを指摘することでこれを支援できます。

$ cat script.sh
#!/bin/sh
cat file | cat
$ shellcheck script.sh

In script.sh line 2:
cat file | cat
    ^-- SC2002: Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead.

これをシェルに自動的に実行させることは、シェルスクリプトの性質上困難です。スクリプトの実行方法は、親プロセスから継承された環境と、使用可能な外部コマンドの特定の実装に依存します。

シェルは必ずしも何catであるかを知っているわけではありません。潜在的には、の任意の場所からのコマンド$PATH、または関数です。

それは、内蔵された場合は、コマンド(それは一部のシェルであってよい)、それはですそれはそのビルトインの意味を知っているだろうとのパイプラインを再編成する能力持っているcatコマンドを使用します。それを行う前に、パイプラインの次のコマンドについて、元のコマンドの後に追加で仮定する必要がありcatます。

標準入力からの読み取りの動作は、パイプに接続されている場合とファイルに接続されている場合では若干異なることに注意してください。パイプはシーク可能でないため、パイプラインの次のコマンドが何をするかに応じて、パイプラインが再配置された場合、異なる動作をする場合としない場合があります(入力がシーク可能かどうかを検出し、そうであるかどうかによって異なることを行う場合がありますそうではありません、いずれにしても、それは異なる振る舞いをするでしょう)。

この質問は(非常に一般的な意味で)「自分で構文エラーを修正しようとするコンパイラはありますか?」(Software Engineering StackExchangeサイトで)ですが、その質問は明らかに無駄なデザインパターンではなく構文エラーに関するものです。 。ただし、意図に基づいてコードを自動的に変更するという考え方はほぼ同じです。


シェルがcatパイプラインの他のコマンド(as-ifルール)を認識し、それに応じて動作することは、シェルにとって完全に準拠しています。それは無意味で難しすぎるため、ここでは実行しません。
マイケルホーマー

4
@MichaelHomerはい。ただし、同じ名前の関数を使用して標準コマンドをオーバーロードすることもできます。
クサラナンダ

2
@PhilipCoulingパイプラインコマンドがどれも気にしないことがわかっている限り、これは完全に準拠しています。シェルは、外部結果が見分けがつかない限り許可されている限り、ユーティリティを組み込み関数またはシェル関数に置き換えることを特に許可されており、実行環境の制限はありません。あなたのケースでは、cat /dev/tty興味深いものであるだろうとは多少異なる場合が<
マイケルホーマー

1
@MichaelHomer は、外部結果が区別できない限り許可されます。つまり、このような方法で最適化されたユーティリティセット全体の動作は決して変更できません。それは究極の依存性地獄でなければなりません。
アンドリューヘンレ

3
@MichaelHomer他のコメントが言ったように、もちろん、シェルは、OPの入力が与えられると、catコマンドを実行せずにコマンドが実際に何をするかを知ることができないことを完全に適合してます。すべてのあなた(およびシェル)を知るために、OPコマンド持つcatインタラクティブ猫のシミュレーションである彼女のパスでは、「MYFILEは」ちょうど保存されたゲームの状態で、command1かつcommand2現在の再生セッションに関するいくつかの統計を後処理しています...
アレフゼロ

34

無駄ではないからです。

の場合cat file | cmd、fd 0(stdin)はcmdパイプになり、その場合cmd <file、通常のファイル、デバイスなどになります。

パイプには通常のファイルとは異なるセマンティクスがあり、そのセマンティクスは通常のファイルのセマンティクスのサブセットではありません

  • 通常のファイルは意味のある方法でselect(2)編集またはpoll(2)編集できません。そのselect(2)上で常に「準備完了」を返します。epoll(2)Linuxのような高度なインターフェイスは、通常のファイルでは機能しません。

  • Linux上のシステムコール(あるsplice(2)vmsplice(2)tee(2))パイプでのみ作業[1]

以来catあまり使用され、それが組み込まれている余分なプロセスを避けることができますシェルとして実装することができますが、あなたはそのパスで開始したら、同じことは、ほとんどのコマンドで行うことができる-遅く&clunkierにシェルを変換しますperlまたはpython。代わりに、継続用の使いやすいパイプのような構文を使用して、別のスクリプト言語を記述する方がおそらく良いでしょう;-)

[1]その機会に対応していない簡単な例をご覧になりたい場合は、ここのコメントにいくつかの説明を載せた「exec binary from stdin」git gistご覧くださいcatUUoCなしで動作させるために内部に実装すると、2倍または3倍大きくなります。


2
実際、ksh93 cat内部のような外部コマンドを実装しています。
jrw32982は、Monica

3
cat /dev/urandom | cpu_bound_programread()別のプロセスでシステムコールを実行します。たとえばLinuxでは、より多くの乱数を生成する実際のCPU作業(プールが空の場合)はそのシステムコールで行われるため、別のプロセスを使用すると、別のCPUコアを利用して入力としてランダムデータを生成できます。たとえば、ランダムな数字を含む1 GBのテキストファイルを生成する最速の方法
ピーターコーデス

4
さらに重要なことは、ほとんどの場合、機能しlseekないことを意味します。 cat foo.mp4 | mpv -動作しますが、mpvまたはmplayerのキャッシュバッファーよりも後方にシークすることはできません。しかし、ファイルからリダイレクトされた入力を使用すると、できます。 cat | mpv -MP4 moovのファイルの先頭にアトムがあるかどうかを確認する1つの方法です。したがって、MP4を最後まで検索せずに再生できます(つまり、ストリーミングに適している場合)。リダイレクト/dev/stdinを使用して実行することで、シークできないファイルのプログラムをテストする他のケースを想像するのは簡単catです。
ピーターコード

これはを使用する場合にさらに当てはまりますxargs cat | somecmd。ファイルパスがコマンドバッファーの制限を超えている場合、複数回xargs実行catすると連続したストリームになりますが、xargs somecmd直接使用somecmdすると、シームレスな結果を達成するために複数で実行できないために直接失敗することがよくあります。
タスクセット

17

役に立たない猫を見つけるのは本当に難しいからです。

私が書いたシェルスクリプトがありました

cat | (somecommand <<!
...
/proc/self/fd/3
...
!) 0<&3

catを介して呼び出されたために削除された場合、実稼働環境でシェルスクリプトは失敗しましたsu -c 'script.sh' someuser。明らかに不必要なcatため、標準入力の所有者が、スクリプトを実行しているユーザーに変更して、/proc作業を介してスクリプトを再度開くようにしました。


このケースは、単純なモデルcatに1つのパラメーターが続くだけであるため、シェルcatは最適化されたショートカットではなく実際の実行可能ファイルを使用する必要があるため、非常に簡単です。ただし、実際のプロセスでは、おそらく異なる資格情報または非標準の標準入力に関する良い点があります。
ミッコランタライネン

13

tl; dr:コストが予想されるメリットを上回るため、シェルは自動的にそれを行いません。

他の答えは、パイプである標準入力とファイルである標準入力の技術的な違いを指摘しています。それを念頭に置いて、シェルは次のいずれかを実行できます。

  1. catファイルとパイプの区別を保持しながら、組み込みとして実装します。これにより、execと、場合によってはforkのコストを節約できます。
  2. ファイル/パイプが重要かどうかを確認するために使用されるさまざまなコマンドの知識を使用して、パイプラインの完全な分析を実行し、それに基づいて行動します。

次に、各アプローチのコストと利点を考慮する必要があります。利点は非常に簡単です:

  1. いずれの場合も、exec(of cat)を避けてください
  2. 2番目のケースでは、リダイレクト置換が可能な場合、フォークを回避します。
  3. あなたは、パイプを使用する必要があります場合には、可能性があるフォーク/のvforkを回避することが可能時にはことが、しばしばありません。これは、cat-equivalentを残りのパイプラインと同時に実行する必要があるためです。

したがって、フォークを回避できる場合は特に、CPU時間とメモリを少し節約できます。もちろん、機能を実際に使用する場合にのみ、この時間とメモリを節約できます。そして、あなたは本当にfork / execの時間を節約しているだけです。大きなファイルでは、ほとんどの時間はI / O時間(つまり、猫がディスクからファイルを読み取る時間)です。だからあなたは尋ねる必要があります:catパフォーマンスが実際に重要なシェルスクリプトで(無駄に)どのくらいの頻度で使用されますか?他の一般的なシェルビルトインと比較してください。重要な場所で使用される頻度の10分の1でさえ、(無駄に)使用されるtestcatは想像しにくいtestです。それは推測です、私は測定していません。これは、実装を試みる前にあなたがやりたいことです。(または同様に、他の誰かに機能要求などで実装するように依頼します。)

次に尋ねる:費用はいくらですか。頭に浮かぶ2つのコストは次のとおりです。(a)シェルにコードを追加すると、サイズが大きくなり(したがってメモリ使用量が増える)、より多くのメンテナンス作業が必要になり、バグなどが発生します。(b)下位互換性の驚き。POSIXではcat、GNU coreutils catなどの多くの機能が省略されているため、cat組み込み関数が何を実装するかを正確に注意する必要があります。

  1. 追加のビルトインオプションはおそらくそれほど悪くはありません。既に多くのビルトインが存在する場所にもう1つビルトインを追加します。役立つことを示すプロファイリングデータがあれば、お気に入りのシェルの作成者にそれを追加するよう説得することができます。

  2. パイプラインの分析に関しては、シェルが現在このようなことをしているとは思いません(パイプラインの終わりを認識し、分岐を回避できるものもあります)。基本的に、シェルに(プリミティブ)オプティマイザーを追加することになります。オプティマイザーは、多くの場合、複雑なコードであり、多くのバグの原因であることが判明しています。そして、これらのバグは驚くべきものです。シェルスクリプトにわずかな変更を加えると、バグを回避またはトリガーする可能性があります。

追記:猫の無用な使用にも同様の分析を適用できます。利点:読みやすい(ただし、command1が引数としてファイルを取る場合は、おそらくそうではありません)。コスト:追加のforkおよびexec(さらに、command1が引数としてファイルを取ることができる場合、おそらくより混乱したエラーメッセージ)。分析でcatを無駄に使用するように指示された場合は、先に進みます。


10

このcatコマンドは-stdinのマーカーとして受け入れることができます。(POSIX、「ファイルが '-'の場合、catユーティリティはシーケンスのその時点で標準入力から読み取るものとします。」)これにより、ファイルまたはstdinの単純な処理が可能になります。

シェル引数$1が次の2つの些細な選択肢を検討してください-

cat "$1" | nl    # Works completely transparently
nl < "$1"        # Fails with 'bash: -: No such file or directory'

もう1つのcat便利な方法は、単にシェル構文を維持するために意図的にノーオペレーションとして使用される場合です。

file="$1"
reader=cat
[[ $file =~ \.gz$ ]] && reader=zcat
[[ $file =~ \.bz2$ ]] && reader=bzcat
"$reader" "$file"

最後に、UUOCを実際に正しく呼び出すことがcatできるのは、通常のファイル(デバイスまたは名前付きパイプではない)であることがわかっているファイル名で使用され、コマンドにフラグが指定されていない場合だけです。

cat file.txt

他の状況では、catそれ自体の操作が必要になる場合があります。


6

catコマンドは、シェルが必ずしも実行できない(または少なくとも、簡単に実行できない)ことを実行できます。たとえば、タブ、キャリッジリターン、改行など、通常は表示されない文字を印刷するとします。シェル組み込みコマンドのみでこれを行う方法があるかもしれませんが、頭の上のものは考えられません。GNUバージョンのcatは-A-v -E -T1 つまたは複数の引数を使用してこれを実行できます(ただし、catの他のバージョンについては知りません)。-nまた、(GNU以外のバージョンでこれができる場合はIDK を使用して)各行の先頭に行番号を付けることもできます。

catのもう1つの利点は、複数のファイルを簡単に読み取ることができることです。そうするには、単にを入力しcat file1 file2 file3ます。シェルで同じことを行うには、注意が必要になりますが、慎重に作成されたループでも同じ結果が得られる可能性があります。そうは言っても、そのような単純な代替案が存在する場合、そのようなループを書くのに本当に時間をかけたいですか?しません!

catはプリコンパイルされたプログラムであるため、catを使用してファイルを読み取ると、おそらくシェルよりもCPUの使用量が少なくなります(明らかな例外は、catが組み込まれたシェルです)。大規模なファイルのグループを読み取ると、これが明らかになる場合がありますが、自分のマシンでこれを行ったことがないため、確信がありません。

catコマンドは、コマンドが強制的に標準入力を受け入れない場合にも役立ちます。以下を考慮してください。

echo 8 | sleep

数字の「8」は、標準入力を受け入れることを意図したものではないため、「sleep」コマンドでは受け入れられません。したがって、sleepはその入力を無視し、引数がないことを訴えて終了します。ただし、次のいずれかを入力した場合:

echo 8 | sleep $(cat)

多くのシェルはこれをsleep 8に拡張し、スリープは終了する前に8秒間待機します。sshでも同様のことができます。

command | ssh 1.2.3.4 'cat >> example-file'

1.2.3.4のアドレスを持つマシン上の「example」ファイルを追加するこのコマンドと「command」から出力されるもの。

そして、それは(おそらく)表面を傷つけているだけです。必要であれば、猫の有用な例をもっと見つけることができると確信していますが、この記事はそれだけで十分です。したがって、これらのシナリオ(および他のいくつかのシナリオ)をすべて予測するようにシェルに要求することは実際には実行可能ではありません。


最後の文は「簡単に実行できません」で終了します
Basile Starynkevitch

3

ユーザーが持っている可能性があることを忘れないでくださいcat、彼には$PATHまさにPOSIXされていないcat(しかし、何かどこかのログを記録でき、おそらくいくつかの変種)。その場合、シェルにそれを削除させたくありません。

PATH 動的に変更し、可能性がありcat ますが、それが信じるものではありません。夢のような最適化を行うシェルを書くのは非常に難しいでしょう。

また、実際にcat は、非常に迅速なプログラムです。それを避ける実用的な理由はほとんどありません(美学を除く)。

FOSDEM2018でのYann Regis-Gianasによる優れたParsing POSIX [s] hellトークもご覧ください。それは、あなたがシェルで夢見ていることをしようとしないようにする他の正当な理由を与えます。

シェルのパフォーマンスが本当に問題である場合、誰かが洗練されたプログラム全体のコンパイラ最適化、静的ソースコード分析、およびジャストインタイムコンパイル技術を使用するシェルを提案したでしょう会議、例:SIGPLAN)。悲しいことに、興味深い研究トピックとしても、現在は研究機関やベンチャーキャピタリストから資金提供を受けていないため、努力するだけの価値がないと推測しています。つまり、シェルを最適化するための重要な市場はおそらくないでしょう。あなたがそのような研究に費やす50万ユーロがあるなら、あなたはそれをする誰かを簡単に見つけるでしょう、そして、それは価値のある結果を与えると信じています。

実用的な面では、パフォーマンスを改善するために、より優れたスクリプト言語(Python、AWK、Guileなど)の小さな(100行未満の)シェルスクリプトを書き換えるのが一般的です。また、(多くのソフトウェアエンジニアリング上の理由から)大きなシェルスクリプトを記述することは合理的ではありません:100行を超えるシェルスクリプトを記述する場合、より読みやすい言語で(読みやすさやメンテナンス上の理由でさえ)書き換えることを考慮する必要があります:プログラミング言語としてのシェルは非常に貧弱です。ただし、多くの大きな生成されたシェルスクリプトがあり、正当な理由(GNU autoconfで生成されたconfigureスクリプトなど)があります。

巨大なテキストファイルに関しては、それらを単一の引数catとして渡すことは良い習慣ではなく、ほとんどのシステム管理者はそれを知っています(シェルスクリプトの実行に1分以上かかると、最適化を検討し始めます)。大きなギガバイトのファイルの場合、それらを処理するのに適したツールではありませんcat


3
「それを回避する実際的な理由はほとんどありません」- cat some-huge-log | tail -n 5走るのを待っている人(tail -n 5 some-huge-log最後までまっすぐにジャンプできるのに対し、cat前から後ろだけを読むことができる人)は同意しません。
チャールズダフィー

コメントチェックアウト^ catテスト用に作成された数十GBの範囲の大きなテキストファイルをチェックすると、かなり時間がかかります。お勧めしません。
Sergiy Kolodyazhnyy

1
ところで、「シェルを最適化するための重要な市場はありません」-ksh93 最適化シェルであり、非常に優れたシェルです。それはして、しばらくの間、成功裏に商用製品として販売します。(残念ながら、商業的にライセンスされているため、十分にニッチになっていないため、低コストのクローンやその他の能力は低いが無料のコストの後継者が、ライセンスを支払う意思のあるサイト以外の世界を引き継いで、状況につながります今日あります)。
チャールズダフィー

(ご指摘の特定の手法を使用していませんが、率直に言って、これらの手法プロセスモデルを考えると意味がありません。適用される手法は、よく、よく適用され、効果があります)。
チャールズダフィー

2

@Kusalanandaの回答(および@alephzeroのコメント)に加えて、catは何でもかまいません。

alias cat='gcc -c'
cat "$MYFILE" | command1 | command2 > "$OUTPUT"

または

echo 'echo 1' > /usr/bin/cat
cat "$MYFILE" | command1 | command2 > "$OUTPUT"

cat(単独)またはシステム上の/ usr / bin / catが実際にcatの連結ツールである理由はありません。


3
の動作以外はcatPOSIXで定義されているため、大きく異なることはありません。
ロアイマ

2
@roaima:今PATH=/home/Joshua/bin:$PATH cat ...何をcatしているのか知っていますか?
ジョシュア

1
@ジョシュアは本当に重要ではありません。私たちはどちらcatもオーバーライドできることを知っていますが、他の何かに置き換えたくないだけであることも知っています。私のコメントは、POSIXが存在することが合理的に予想される特定の(サブセットの)動作を義務付けていることを指摘しています。時々、標準ユーティリティの動作を拡張するシェルスクリプトを作成しました。この場合、シェルスクリプトは、追加の機能があったことを除いて、置き換えたツールと同じように動作し、動作しました。
ロアイマ

@Joshuaは:ほとんどのプラットフォームでは、シェルは知っている(または可能性があり、ディレクトリはPOSIXのコマンドを実行する実行可能ファイルを保持している知っています)。そのため、エイリアスの展開とパスの解決が完了するまで置換を延期し、に対してのみ行うことができ/bin/catます。(そして、あなたはそれをあなたがオフにすることができるオプションにします。)または、あなたはcatシェルビルトインを作り(おそらく/bin/cat複数の引数のためにフォールバックしますか?)、ユーザーが外部バージョンを通常のものにしたいかどうかを制御できます方法、でenable cat。のようなkill。(bash command catが機能すると思っていましたが、ビルトインはスキップしません)
Peter Cordes

エイリアスを指定すると、シェルはcatその環境では通常のを参照していないことを認識しますcat。明らかに、エイリアスが処理された後に最適化を実装する必要があります。シェルビルトインは、常にパスの先頭に追加される仮想ディレクトリ内のコマンドを表すと考えています。シェルの組み込みバージョンのコマンド(たとえばtest)を避けたい場合は、パスのあるバリアントを使用する必要があります。
ミッコランタライネン

1

catの2つの「役に立たない」使用法:

sort file.txt | cat header.txt - footer.txt | less

...ここでcatは、ファイルとパイプ入力を混合するために使用されます。

find . -name '*.info' -type f | sh -c 'xargs cat' | sort

...ここでxargsは、事実上無限の数のファイル名を受け入れ、cat必要に応じて何度でも実行できますが、すべて1つのストリームのように動作します。そのため、これは、直接使用xargs sortしない大きなファイルリストに対して機能します。


これらのユースケースはどちらも、シェルを組み込み、ステップインのみで、cat引数を1つだけ指定して呼び出すことで簡単に回避できます。特に、sh文字列が渡され、直接xargs呼び出す場合はcat、シェルが組み込み実装を使用する方法はありません。
ミッコランタライネン

0

他のこととは別に、cat-checkはパフォーマンスのオーバーヘッドを追加し、どの使用catが実際に役に立たないかについて混乱を招きcatます。

コマンドが標準ストリームを処理する場合、標準ファイル記述子の読み取り/書き込みのみを考慮する必要があります。コマンドは、stdinがシーク可能/リシーク可能かどうか(パイプまたはファイルを示す)を知ることができます。

どのプロセスが実際にそのstdinコンテンツを提供するかをチェックするミックスに追加する場合、パイプの反対側でプロセスを見つけ、適切な最適化を適用する必要があります。これは、カイルジョーンズによるSuperUserの投稿に示されているように、シェル自体の観点から、また、

(find /proc -type l | xargs ls -l | fgrep 'pipe:[20043922]') 2>/dev/null

リンクされた投稿に示されているように。これは、さらに3つのコマンド(追加fork()のsとexec()s)と再帰的トラバーサル(非常に多くのreaddir()呼び出し)です。

Cとシェルのソースコードに関しては、シェルはすでに子プロセスを知っているので、再帰の必要はありませんが、最適化のタイミングcatと実際に役に立たないタイミングをどのように知ることができますか?実際、catには次のような便利な用途があります。

# adding header and footer to file
( cmd; cat file; cmd ) | cmd
# tr command does not accept files as arguments
cat log1 log2 log3 | tr '[:upper:]' '[:lower:]'

このような最適化をシェルに追加することは、おそらく無駄であり、不必要なオーバーヘッドです。Kusalandaの答えがすでに述べたように、UUOCは、ユーザーがコマンドを組み合わせて最良の結果を得るための最適な方法を理解していないことを重視しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.