证明这一点的一种非常简单的方法是运行
mkfifo /tmp/a
read -t 1 a < /tmp/a
读取永不返回。
Bash手册说: 此选项仅在以下情况下有效 read是从终端,管道或其他特殊文件读取输入; 从常规文件中读取时没有效果
但/ tmp / a是管道,ls的输出是
ls -l /tmp/a
prw-r--r-- 1 root root 0 Feb 4 22:18 /tmp/a
bash版本是:
GNU bash,版本4.3.46(1) - release(x86_64-pc-linux-gnu) 版权所有(C)2013 Free Software Foundation,Inc。
操作系统是:
Ubuntu 16.04.1 LTS
答案 0 :(得分:1)
当您从管道中读取时,也需要有人写入管道。 “管道”只是一种沟通机制。它本身并不“生成”任何输入;它只是将其输入传递给它的输出端。您似乎只是在阅读,但没有人写信给/tmp/a
。
当read
等待输入时,从另一个终端执行echo hello > /tmp/a
,您会看到read
返回,a
的值为“hello”。
答案 1 :(得分:1)
请参阅我在 unix.stackexchange.com 上的详细回答。
TL;DR:您的 -t
标志似乎不起作用,因为 read
甚至没有执行,因为这是您的 shell 被阻止,而不是您的命令。< /p>
在执行您的 read
命令之前,bash
会尝试打开 /tmp/a
,这是一个阻塞操作。打开一个命名管道来读取块,直到其他人打开它来写入。
你可以用一个错误的命令来检查:
mkfifo my_fifo
a_command_that_does_not_exist < my_fifo
(你的 shell 被阻塞,直到有人打开 my_fifo
进行写入,然后它才会告诉你 command not found
)
解决方案:read -t 1 a <> /tmp/a
(更多关于 unix.stackexchange.com)
答案 2 :(得分:0)
我只是确认由于竞争条件超时在管道流上不起作用。子 shell 在输入可用之前执行 read
语句。
运行:
echo 'hello' | {
if read -t0
then echo 'Input is available.'
else echo 'No input available on the FD.'
fi
}
输出:
No input available on the FD.
在 :
之前引入一个虚拟的 wait 1
NOP 命令(或 read
),可以改变交易:
echo 'hello' | {
:
if read -t0
then echo 'Input is available.'
else echo 'No input available on the FD.'
fi
}
然后突然:
Input is available.