Я пытаюсь использовать bash coproc
, и я Столкнулся с трудностями, скорее всего с буферизацией. У меня есть сложная команда, которая принимает линейный ввод со стандартного ввода и выводит строку на стандартный вывод для каждой строки ввода. В командной строке эта команда отлично работает для каждой строки, но когда я помещаю ее в coproc и читаю из ${COPROC[0]}
FD, чтение блокируется.
Я могу воссоздать это поведение с помощью paste
, но не с cat
. Я ожидаю, что paste
и cat
сделают то же самое, если не будут переданы параметры. Это происходит при запуске непосредственно в командной строке:
$ cat
Hello World!<RETURN>
Hello World!^D
$ paste
Hello World!<RETURN>
Hello World!^D
$
(RETURN
и ^D
добавлены для иллюстрации)
Но когда я помещаю их в coproc, они ведут себя по-другому - cat
строго буферизуется строкой, тогда как paste
, похоже, работает с гораздо большим буфером:
$ coproc cat
$ echo 'Hello world!' >&${COPROC[1]}
$ read -ru ${COPROC[0]} line; echo $line
Hello world!
$ kill $COPROC_PID
[3]+ Terminated coproc COPROC cat
$
$ coproc paste
[3] 42657
$ echo 'Hello world!' >&${COPROC[1]}
$ read -ru ${COPROC[0]} line; echo $line
#### read blocks here until ^C ####
Я думаю, причина этого в том, что paste
настраивает свой режим буферизации в зависимости от того, к чему он подключен, тогда как cat
всегда находится в режиме линейной буферизации.
Есть ли способ заставить paste
(или другую общую команду) буферизовать строку в coproc?
Немного поэкспериментировав, я обнаружил, что могу воссоздать аналогичное поведение без coprocs и вместо этого просто соединяет cat
и paste
:
$ cat | cat
Hello World!<RETURN>
Hello World!^D
$ cat | paste
Hello World!<RETURN>
Hello World!^D
$ paste | cat
Hello World!<RETURN>
#### command blocks here until ^C ####
(RETURN
и ^D
добавлены для иллюстрации)
- Сначала мы соединяем
cat
сcat
и получаем буферизацию строк на всем пути. - Затем мы передаем
cat
вpaste
, а также получаем буферизацию строк на всем пути. - Наконец, мы передаем
paste
вcat
и не получаем буферизацию строк.
Похоже, это указывает на то, что paste
будет строчно буферизовать свой стандартный вывод в интерактивном режиме, но в противном случае он будет использовать гораздо больший буфер.