概念的には、ストリームは「文字」または「アトム」のシーケンスです。つまり、バイナリ ストリームは 0 と 1 のシーケンスです。しかし、Linux の標準ストリームでは、「読み取り」を要求する bash スクリプトを作成すると、1 行 (「ENTER」で終わる) が「文字」として扱われると思いますが、確信はありません。これは、1 つの「アトム」が文字列であり、アトムが ENTER で区切られていることを示唆しています。また、他のプログラムでは、入力として文字列ではなく、他のデータ型を受け取ると想定しています。
私の理解は正しいでしょうか? 標準ストリーム内のアトム/文字とは何ですか? また、プログラムはどのようにしてファイルをアトムに分割するかを知るのでしょうか?
答え1
基本的に、パイプ/ファイル/ソケット、または接続したstdin/stdout/stderrはストリーム(*)です。バイト関連するシステムコールはread()
とでありwrite()
、それらの POSIX の説明では次のように述べられています。
write() 関数は、buf が指すバッファから nbyte バイトをファイルに書き込もうとします [...]
そして
read() 関数は、開いているファイル記述子 fildes に関連付けられたファイルから nbyte バイトを読み取ろうとします。[...]
また、POSIXではバイトはオクテットと正確に等しいと定義されていますつまり、8 ビットの単位です。
したがって、8 ビット バイトは、一度に読み書きできる最小単位であり、いわば「アトム」です。
しかし、さまざまなユーティリティが何を行うかは別の問題です。read
デフォルトでは は 1 行を読み取りますが、ライブラリ関数も同様ですfgets()
。シェルによっては、代わりに固定数のバイトを読み取るように要求できる場合がありますread
。たとえば、Bash の場合:
$ echo foo | ( read -n 1 a; echo "first: $a"; read -n 1 b; echo "second: $b" )
first: f
second: o
ただし、Bashはread
ロケールに従ってカウントを次のように取ることに注意してください。文字、マルチバイトの可能性があります。しかし、それは個々の文字を読み取ることを妨げるものではありません。バイトその代わり:
$ echo äöä | (read -n 1 a; echo "first: $a"; LC_ALL=C read -n 1 b; echo "second: $b" )
first: ä
second: �
(* もありますデータグラムソケットはバイト単位ですが、メッセージ(0 バイト以上の) がソケットに送信されます。適切に設定されたデータグラム ソケットを stdin/stdout/stderr に接続することもできますが、実際にそうする人はほとんどいません。