Linux bash`read-t`不';不要在管道上工作
演示这一点的一个非常简单的方法是运行Linux bash`read-t`不';不要在管道上工作,linux,bash,shell,Linux,Bash,Shell,演示这一点的一个非常简单的方法是运行 mkfifo /tmp/a read -t 1 a < /tmp/a bash版本是: GNUBash,版本4.3.46(1)-发行版(x86_64-pc-linux-GNU) 版权所有(C)2013免费软件基金会 操作系统是: Ubuntu 16.04.1 LTS 当你从管道里读东西的时候,也需要有人在管道里写字。“管道”只是一种沟通机制。它不会自行“生成”任何输入;它只是将输入端的数据传递到输出端。看起来您只是在阅读,但没有人向/tmp/a写信
mkfifo /tmp/a
read -t 1 a < /tmp/a
bash版本是:
GNUBash,版本4.3.46(1)-发行版(x86_64-pc-linux-GNU)
版权所有(C)2013免费软件基金会
操作系统是:
Ubuntu 16.04.1 LTS
当你从管道里读东西的时候,也需要有人在管道里写字。“管道”只是一种沟通机制。它不会自行“生成”任何输入;它只是将输入端的数据传递到输出端。看起来您只是在阅读,但没有人向
/tmp/a
写信
当read
等待输入时,从另一个终端执行echo hello>/tmp/a
,您将看到read
返回并且a
具有值“hello”
请在此处详细阅读管道:我刚刚确认,由于争用条件,超时在管道流上不起作用。在输入可用之前,子shell正在执行
read
语句
运行:
echo'hello'|{
如果读取-t0
然后echo“输入可用”
else echo“FD上没有可用的输入”
fi
}
产出:
FD上没有可用的输入。
在读取之前引入虚拟:
NOP命令(或等待1
),可以更改交易:
echo'hello'|{
:
如果读取-t0
然后echo“输入可用”
else echo“FD上没有可用的输入”
fi
}
然后突然:
输入可用。
请参阅我的详细答案
TL;DR:您的-t
标志似乎不起作用,因为read
甚至没有执行,因为被阻止的是您的shell,而不是您的命令
在执行read
命令之前,bash
尝试打开/tmp/a
,这是一个阻塞操作。打开命名管道以读取块,直到其他人打开它进行写入
您可以使用错误的命令进行检查:
mkfifo my_fifo
a_command_that_does_not_exist < my_fifo
mkfifo我的fifo
不存在的命令
(您的shell将被阻止,直到有人打开my_fifo
进行写入,然后才会告诉您未找到命令
)
解决方案:read-t1a/tmp/a
(更多信息)当我执行:strace bash-c“read-t3aread
会一直被阻止,直到有人写入它。timeout
不会有太大变化。它只是停止read
进一步等待。但真正的问题是没有人在向管道写入。您可能想阅读链接的手册,以了解管道的工作方式。@P.P不,read
不会被阻止,因为这是在上面的strace
输出中,没有打开的。请参阅我的答案。这个争用条件是一个有趣的事实。只是对您的措辞进行了更正:超时确实对管道流有效(请尝试-t0.1
),这是-t0
这里的问题:它可能工作,也可能不工作,因为在bash分叉之后,没有任何东西可以保证|
左侧的child1将在右侧的child2之前执行。这不是OP有BTW的问题。bash手册页和read
帮助明确提到-t0
如果超时为0,则将作为,read立即返回,不尝试读取任何数据,仅当指定的文件描述符上有可用的输入时才返回成功。
因此,如果您只想检查可用性,而不想读取实际数据,则必须使用-t0
而不是-t0.1
。我只是对您的“超时在管道上不起作用”做出了反应向你展示它的功能。
mkfifo my_fifo
a_command_that_does_not_exist < my_fifo