bash`read -t`不适用于管道

时间:2017-02-04 14:57:30

标签: linux bash shell

证明这一点的一种非常简单的方法是运行

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

3 个答案:

答案 0 :(得分:1)

当您从管道中读取时,也需要有人写入管道。 “管道”只是一种沟通机制。它本身并不“生成”任何输入;它只是将其输入传递给它的输出端。您似乎只是在阅读,但没有人写信给/tmp/a

read等待输入时,从另一个终端执行echo hello > /tmp/a,您会看到read返回,a的值为“hello”。

在此处详细了解管道:http://man7.org/linux/man-pages/man7/pipe.7.html

答案 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.