1. 序章

Linuxには複数のユーティリティがあり、ファイルと標準入力に作用します。 さらに、それらに向けられたデータの連続ストリームに作用することさえできるものもあります。

このチュートリアルでは、 grep (グローバル正規表現印刷)コマンドとその方法を扱います。

  • データの連続ストリームをgrepに渡します
  • そのデータをフィルタリングして出力します

特に、ストリームを定義し、ストリーム操作について説明します。 その後、grepがストリームとファイルを処理する方法について簡単に説明します。 次に、特定のツールによって生成された連続ストリームが表示されます。 最後に、 grepは連続ストリームで使用され、バッファリング制御も示します。

このチュートリアルのコードは、GNU Bash5.1.4を使用したDebian11(Bullseye)でテストしました。 これはPOSIXに準拠しており、そのような環境で機能するはずです。

2. ストリーム

最も基本的なレベルでは、streamは単なるデータのパイプラインです。 「with」ではなく「for」という単語の選択に注意してください。 これは、ストリームが存在するためにデータが必要ないという事実を考慮に入れているためです。

キーボードについて考えてみましょう。 その入力デバイス用のストリームがありますが、それはデータを供給するために常にキーを叩くという意味ではありません。 実際には、関心のあるプロセスは、まるでラジオ局であるかのようにストリームをサブスクライブできます。

彼らはそれを複数の方法で行います:

プロセス間でシグナルを送信してイベントを通知することはできますが、通常、プロセスはメタデータとともに実際のデータを保持しません。 一方、ソケットは主にネットワーキングに使用されます。 実際、ソケットはネットワークパイプとほぼ同じです。

これにより、ストリームを一般的に操作することになります。これが私たちの主な関心事です。

3. ストリーム操作

ストリームリダイレクトまたは直接配管のどちらを使用する場合でも、ストリームを変更および迂回させることができます。

3.1. リダイレクション

一般に、リダイレクトする手段はたくさんあります。

$ echo 'Data.' >> file.ext
$ cat file.ext
Data.
$ echo 'Data.' | cat
Data.

上記のどちらの場合も、リダイレクト演算子を扱っています。 まず、>>を使用してechoデータをファイルに追加します。 次に、 cat (連結)を介して出力します。 その後、|を使用して同じ情報をcatに直接パイプします。

重要なことに、パイプにはほとんどの場合バッファーがあります

3.2. バッファリング

バッファの使用は、多くの場合、特定の量が転送のためにすでにロードされているか、一方の端が終了しない限り、情報が通過しないことを意味します。 特に、終了は、特殊文字を介したプロセスまたはストリームで行うことができます。 つまり、 buffer は、データが一時的に蓄積される場所として定義できます。

一部のコマンドは、バッファを直接使用します。

4. grep

grepツールには内部バッファリングがあります。 通常、ファイル操作中は単独で機能します。 一方、 grep はストリームでも機能し、ストリーム自体が2番目のバッファー層を提供します。

4.1. ストリーム

実際、ストリームリダイレクトを介してgrepにデータを渡すことができます。

$ echo 'Content.' | grep 'Con'
Content.

この例では、処理のために文字列を直接パイプ処理します。 特に、stdoutをパイプ経由でリダイレクトします。 文字列でgrepが実行されると、すべてのプロセスがパイプとともに終了します。

ただし、別の方法があります。

4.2. ファイル

もちろん、 grep は、ファイル名を使用するだけでファイルを直接操作できます。

$ echo 'Content.' > file.ext
$ grep 'Con' file.ext
Content.

しかし、ファイルの変更を監視したい場合はどうでしょうか。 別のツールと組み合わせることで、まさにそれが可能になります。

5. テールを使用した連続ストリーム

tail コマンドには、 -f (フォロー)フラグがあります。このフラグは、実行直後に終了するのではなく、ファイルの更新を待機して出力に追加します。

たとえば、ある端末でファイルの末尾の末尾を開始し、別の端末でそのファイルにデータを送信すると、最初の端末でも同じデータが表示されると予想されます。 これを実際に見てみましょう。

まず、tailを実行します。

$ tail -f /file.ext

その後、別の端末でfile.extにデータを送信します。

$ echo 'Line.' >> /file.ext

確かに、もう一方の端にも同じ情報が表示されます。 次に、方程式にフィルターを追加しましょう。

6. grepおよびtailを使用した連続ストリーム処理

今回は、tailからgrepに連続ストリームをパイプします。

$ tail -f /file.ext | grep 'Line'

次に、別の端末のファイルにデータを追加します。

$ echo 'Line.' >> /file.ext

現在、正確な設定によっては、出力が表示されない場合があります。 なんで? バッファリングのため。 パイプとgrepバッファーの両方であり、ラインフィードまたは特定のバイト数まで出力を遅らせる可能性があります。

ただし、これを制御および防止することはできます。

7. バッファ制御

grep–line-buffered フラグを使用すると、具体的なバイト数を待つ代わりに、各行の終了時にバッファを強制的にフラッシュできます。

$ tail -f /file.ext | grep --line-buffered 'Line'

上記の後、file.extに追加されたすべての行がoutputを生成するはずです。 改行文字を出力しない場合、出力は通過しません。

$ echo -n 'Line.' >> /file.ext

変更にもかかわらず、 パイプ自体がデータをバッファリングするインスタンスがまだ発生する可能性があります。 これらの場合、私たちが自由に使えるツールがあります:stdbuf

実際、パイプに同じラインバッファリングを適用できます。

$ stdbuf --output=L tail -f /file.ext | grep --line-buffered 'Line'

L (ライン)に等しい –output オプションを使用すると、パイプの両側にラインバッファリングがあります。

実際には、stdbufを使用してバッファリングを完全に削除できます。 これを実現するために、L0(バッファリングなし)に置き換えます。

$ stdbuf --output=0 tail -f /file.ext | grep 'Line'

設定によっては、この行はfile.extを変更するとすぐに出力を生成するはずです。

8. 結論

この記事では、grepをデータの連続ストリームで使用する方法を説明しました。 さらに、stdbufを介してバッファー制御を適用しました。

連続ストリームで両方のツールを示すために、tailを使用しました。 これがそのようなストリームを生成する唯一の方法ではないことに注意してください。ただし、説明されている方法は、任意のコマンドラインツールで機能するはずです。

結論として、 grep は、そのままの状態で継続的なストリームを処理しますが、その機能をさらに強化および制御するためのオプションがあります。