这行写"foo",睡觉,然后写"bla":
echo "woo"; sleep 2; echo "bla"
Run Code Online (Sandbox Code Playgroud)
我试图在两个连续的读命令中读取它的整个输出:
(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")
Run Code Online (Sandbox Code Playgroud)
第一次阅读打印:
退出代码: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来实现,但显然这不起作用......
问题:“ woo”去了哪里?!
首先woo读取read -t 0.1 -r -N 10,然后此命令失败,因为该命令在设置的超时时间内未收到10个字符或EOF字符。
根据阅读的手册页:
Run Code Online (Sandbox Code Playgroud)-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";)
Run Code Online (Sandbox Code Playgroud)
然后,如果要同时查看传入的输入,则可以添加tee命令,例如:
(echo "woo"; sleep 2; echo "bla") 1> \
>(tee >(IFS=""; read -r -N 10; \
echo "exit code: $? reply: $REPLY";))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
175 次 |
| 最近记录: |