这一行写“foo”,睡觉,然后写“bla”:
echo "woo"; sleep 2; echo "bla"
我试图在两个连续的读命令中读取它的整个输出:
(echo "woo"; sleep 2; echo "bla") 1> \
>(IFS=""; read -t 0.1 -r -N 10; \
echo "exit code: $? reply: $REPLY"; \
sleep 5; \
read -t 0.1 -r -N 10; \
echo "exit code: $? reply: $REPLY")
第一次阅读打印:
退出代码:142回复:
这是预期的,因为142是超时,我用-t 0.1调用了read。但第二次阅读打印:
退出代码:1回复:bla
问题:“呜”哪里去了?!
如果我从输出行中删除sleep 2
,整个过程按预期工作 - 在第一次读取时读取/输出整个“woo \ nbla”序列,并返回1(EOF)。
无论多短,任何睡眠都会重现问题。如果我使用管道重定向输出而不是> 1也没关系。这是Ubuntu。
编辑:我想读入N个字符的缓冲区,并按原样读取输入,而不在分隔符上进行任何分词。因此,-N和IFS =“”。
编辑:这是一个展示一般问题的玩具示例。我想要做的是在bash中实现更智能的tee版本:它应该像tee一样,除了它应该等待其输入生成过程停止,然后刷新其缓冲区,然后退出。如果输入生成过程启动一些僵尸子进程,那么真正的tee会无限期挂起,因为它们会占用stdout句柄并且永远不会被关闭。使用tail --pid工作,但不幸的是它在Windows上不起作用,我需要这个是多平台的。我认为这可以通过在循环中调用read -t -N来实现,但显然这不起作用......
答案 0 :(得分:5)
问题:“呜”哪里去了?!
第一个woo
读取了read -t 0.1 -r -N 10
,然后此命令失败,因为它在设置的超时时间内没有收到10个字符或EOF字符。
-N nchars return only after reading exactly NCHARS characters, unless EOF is encountered or read times out, ignoring any delimiter -t timeout time out and return failure if a complete line of input is not read withint TIMEOUT seconds. The value of the TMOUT variable is the default timeout. TIMEOUT may be a fractional number. If TIMEOUT is 0, read returns success only if input is available on the specified file descriptor. The exit status is greater than 128 if the timeout is exceeded
编辑:我想读入N个字符的缓冲区,并读取输入 原样,在分隔符上没有任何分词。因此,-N和 IFS = “”。
如果你两次调用read
命令,它的每个实例都有一个单独的缓冲区。要解决此问题,请使用单个read
命令并调整或删除超时选项,例如:
(echo "woo"; sleep 2; echo "bla") 1> \
>(IFS=""; read -r -N 10; \
echo "exit code: $? reply: $REPLY";)
然后,如果要同时查看传入输入,可以添加tee
命令,例如:
(echo "woo"; sleep 2; echo "bla") 1> \
>(tee >(IFS=""; read -r -N 10; \
echo "exit code: $? reply: $REPLY";))
答案 1 :(得分:1)
You need to introduce a sleep
right before reading the output from stdout. This sleep
should be at least the same or larger amount that the input.
(echo "woo"; sleep 1; echo "blah") 1> >( IFS=""; \
sleep 1; read -t 0.1 -N 10; echo $REPLY; sleep 2; \
read -t 0.1 -N 10; echo $REPLY)
In your case echo woo
gets gobbled up by the following sleep command. By the time output
redirection happens, all it sees sleep 1; echo "blah"
.
And you have another problem. You are trying to read 10
characters with -N
option, where as you are providing is 3
, causing it to exit with code 142
. Try with -N 4
.
Following will exit with code = 0
;
$ (echo "woo"; sleep 1; echo "blah") 1> >( IFS=""; \
sleep 1; read -t 0.1 -N 4; echo "code: $?"; \
echo $REPLY; sleep 2; read -t 0.1 -N 4; echo "code: $?"; \
echo $REPLY)
code: 0
woo
code: 0
blah