bash `read -t` 在管道上不起作用

yua*_*eng 5 linux bash shell

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

mkfifo /tmp/a
read -t 1 a < /tmp/a
Run Code Online (Sandbox Code Playgroud)

阅读永远不会返回。

Bash 手册说:此选项仅在 read 从终端、管道或其他特殊文件读取输入时有效;从常规文件读取时无效

但是 /tmp/a 是一个管道, ls 的输出是

ls -l /tmp/a
prw-r--r-- 1 root root 0 Feb  4 22:18 /tmp/a
Run Code Online (Sandbox Code Playgroud)

bash 版本是:

GNU bash,版本 4.3.46(1)-release (x86_64-pc-linux-gnu) 版权所有 (C) 2013 Free Software Foundation, Inc.

操作系统是:

Ubuntu 16.04.1 LTS
Run Code Online (Sandbox Code Playgroud)

xhi*_*nne 2

请参阅我在unix.stackexchange.com上的详细答案。

TL;DR:您的-t标志似乎不起作用,因为read甚至没有执行,因为这是您的 shell,而不是您的命令。


在执行read命令之前,bash尝试打开/tmp/a,这是一个阻塞操作。打开命名管道进行读取会阻塞,直到其他人打开它进行写入。

您可以使用错误命令来检查这一点:

mkfifo my_fifo
a_command_that_does_not_exist < my_fifo
Run Code Online (Sandbox Code Playgroud)

(你的 shell 会被阻止,直到有人打开my_fifo进行写入,然后它才会告诉你command not found

解决方案:read -t 1 a <> /tmp/a

(更多信息请访问unix.stackexchange.com