私は.txtファイルの最初の10行と最後の10行を読み取るbashスクリプトを書いています。開始と終了を検索し、grepを使用して発生数を比較します。これらのファイルはかなり大きいので、フルテキストではなくファイルの頭部と末尾のみを読み取ることにしました。ただし、スクリプトを実行すると、大容量ファイルを「完了」するのに長い時間がかかります(最初の10行と最後の10行を読んで比較することが含まれます。これは1〜2分しかかかりません)。
スクリプト出力テキストを見ながらこの問題を発見しました。そのため、コマンドラインから直接head / tail(スクリプトで実行される内容をシミュレートするためにgrepを含む)コマンドを実行するときに同様の時間がかかることを確認することにしました。驚いたことに、コマンドはほぼすぐに実行されました。変だと思ってスクリプトをもう一度実行してみました。今回は、スクリプトがまだ head/tail/grep コマンドを実行していない後、「大きな」ファイルに到達するまで、以前にかかったファイルを叫びます。
bashはコマンドの結果をキャッシュのように保存しますか?また、これらのコマンドの考えられる原因は次のとおりです。
head -n 10 /file/path/myfile.txt | grep -w -c 'lead word'
tail -n 10 /file/path/myfile.txt | grep -w -c 'end word'
実行するのにそれほど時間がかかりますか?
編集:上記のヘッダー/テール行が問題の原因である理由は、ヘッダー/テール行を個別に実行するときに印刷する必要があるエコー行があるためだと思います。ファイルの行サイズを確認してみると、数分で完成したファイルよりも長くなりません。
技術的なレベルでヘッド/テールがどのように機能するかについてもっと詳しく説明できる人はいますか?私はファイルの「前のx行/後のx行」について非常に基本的なことを理解しています。
ベストアンサー1
いいえ、bashは実行ごとに出力が変更される可能性があるため、コマンドの出力をキャッシュしません。 bashには、ファイルが他のプロセスによって変更されたかどうかを追跡するための信頼できる方法はありません。これは非常に重要なので、キャッシュされたかどうかbash
がわかります。結果は依然として効率的です。
しかし、ここには別のものがあります。シェル(たとえばbash
)を使用すると、システムのさまざまな部分と同時に対話できます。たとえば、
- シェル自体
- 複数のシェルやその他のツールで使用される行編集インターフェイスであるGNU Readline
- この
libc
実装は、時にはほとんどすべてのプログラムで混乱する動作を引き起こす可能性があります。 - 端末自体が奇妙な動作をして実際に応答することができます。自分の注文。 (たとえば、BackspackおよびはDelete使用できないか、または互いに置き換えて使用できます。)
- 端末が配置されているGUIウィンドウ(該当する場合)。例えば、私Ctrl特殊キーシーケンス(たとえば、++の後に数字が続く形式)を使用して、Shift端末にUnicode文字を入力できます。u
- すべてのモジュールとドライバを含むカーネル
- もちろん、ハードウェア自体が過熱したり、短絡したり、電源が切れるなどの現象が発生することがあります。
bash
この場合、最大の貢献者はそれ自体ではなく、カーネルに実装されているファイルシステムレベルのキャッシュメカニズムだと言いたいと思います。ファイルを一度読み込むと、その大部分がファイルシステムキャッシュに保存されます。これはこの目的のために予約されたメモリの大きな塊です。
ファイルが 2 番目に動作すると、シェルは物理ハードウェアからの再読み込みをトリガーしませんが、キャッシュからファイルの内容を取得します。 Bashで(再)実行するほとんどすべての作業は、ディスクの読み取りに比べて非常に高速です。これは、遅いディスクの読み取りが失われるため、bashが実際にコマンドを再実行していることを知らない理由です。