Поведение по умолчанию
Хотя read
надежно считывает только одну строку за раз, давайте посмотрим, сколько потребляют три другие общие команды.head -1
печатает только первую строку.Однако для этого он потребляет 8192 байта из стандартного ввода:
$ seq 5000 | tee >(wc >/dev/tty) | ( head -1 >/dev/null; cat) | wc
5000 5000 23893
3141 3140 15701
$ echo $((23893 - 15701))
8192
Команда awk '{exit}'
должна прочитать первую строку и выйти.Для этого, однако, он потребляет 4096 байтов стандартного ввода:
$ seq 5000 | tee >(wc >/dev/tty) | ( awk '{exit}' >/dev/null; cat) | wc
5000 5000 23893
3960 3960 19797
$ echo $((23893 - 19797))
4096
sed 1q
должен завершиться при чтении первой строки, но также потребляет 4096 байтов стандартного ввода:
$ seq 5000 | tee >(wc >/dev/tty) | ( sed 1q >/dev/null; cat) | wc
5000 5000 23893
3960 3960 19797
$ echo $((23893 - 19797))
4096
Величины 8192 и 4096 являются размерами буфера в текущем коде.Можно ожидать, что эти размеры могут измениться от одной версии к следующей версии.
Использование stdbuf
stdbuf
- это утилита, которая пытается контролировать размеры буфера, которые использует команда.stdbuf -i1
пытается установить размер буфера на входе в 1 байт.При применении stdbuf sed 1q
использует только одну строку:
$ (echo First; echo Second) | ( stdbuf -i1 sed 1q>/dev/null; cat)
Second
При seq
в качестве входных данных он по-прежнему использует только одну строку:
$ seq 5000 | tee >(wc >/dev/tty) | ( stdbuf -i1 sed 1q >/dev/null; cat) | wc
5000 5000 23893
4999 4999 23891
Этот же прием не работаетдля head
или awk
.Оба они потребляют несколько кБ, несмотря на stdbuf
:
$ seq 5000 | tee >(wc >/dev/tty) | ( stdbuf -i1 head -1 >/dev/null; cat) | wc
5000 5000 23893
3141 3140 15701
$ echo $((23893 - 15701))
8192
$ seq 5000 | tee >(wc >/dev/tty) | ( stdbuf -i1 awk '{exit}' >/dev/null; cat) | wc
5000 5000 23893
3960 3960 19797
$ echo $((23893 - 19797))
4096
Сводка
В то время как встроенная оболочка read
надежно потребляет только одну строку за раз, внешние команды, такие как sed
, awk
и head
потребляют зависящее от реализации количество стандартного ввода даже при обработке одной строки.
Чтобы ответить на два вопроса:
В текущей реализации возможно использовать только одну строку stdbuf, используя stdbuf -i1 sed 1q
, но нет никаких гарантий, что это продолжит работать в любой будущей версии.
пример stdbuf -i1 sed 1q
указывает, что можно написать утилиту, которая отключит входную буферизацию и, следовательно, потребляет только столько стандартного ввода, сколько необходимо.