Опитвам се да използвам bash coproc
и аз Срещам затруднения, най-вероятно с буферирането. Имам сложна команда, която приема редово-ориентиран вход от stdin и отпечатва ред в stdout, на входен ред. В командния ред тази команда работи добре на базата на ред, но когато я поставя в 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
ще буферира своя stdout, когато е в интерактивен режим, но в противен случай ще използва много по-голям буфер.