Что именно представляет собой отдельный «атом» в стандартном потоке в Linux?

Что именно представляет собой отдельный «атом» в стандартном потоке в Linux?

Концептуально поток — это последовательность «символов» или «атомов», то есть двоичный поток — это последовательность нулей и единиц. Но в стандартных потоках Linux, если я пишу скрипт bash, который запрашивает «read», то я думаю, что он обрабатывает одну строку (заканчивающуюся «ENTER») как «символ», но я не уверен. Это наводит меня на мысль, что один «атом» — это строка, и что атомы разделяются ENTER. Также я предполагаю, что для других программ они не принимают строки в качестве входных данных, а другие типы данных.

На правильном ли я пути? Что такое атомы/символы в стандартном потоке и как программа узнает, как разбить файл на атомы?

решение1

По сути, каналы/файлы/сокеты или что бы вы ни подключили к stdin/stdout/stderr, это потоки(*)байты. Соответствующие системные вызовы — это read()и write(), а их описания POSIX гласят:

Функция write() попытается записать nbyte байт из буфера, на который указывает buf, в файл [...]

и

Функция read() попытается прочитать nbyte байт из файла, связанного с открытым файловым дескриптором, fildes, [...]

Также,POSIX определяет байт как точно равный октету, то есть единица из восьми бит.

Итак, восьмибитный байт — это наименьшая единица, которую вы можете прочитать или записать за один раз, так сказать, «атом».

Но то, что делают различные утилиты, это другой вопрос. readпо умолчанию считывает строку, но то же самое делает и библиотечная функция 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: �

(* Это такжедатаграммасокеты, которые по-прежнему являются байт-гранулированными, но также содержат границы междуСообщения(из нуля или более байтов), отправленных в сокет. Вы, вероятно, могли бы подключить правильно настроенный сокет датаграмм к stdin/stdout/stderr, но вряд ли кто-то когда-либо это делает.)

Связанный контент