Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux bash`read-t`不';不要在管道上工作_Linux_Bash_Shell - Fatal编程技术网

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