【发布时间】:2016-11-23 20:33:26
【问题描述】:
我有一个 Bash 脚本 foo,它接受 STDIN 上的单词列表。脚本应该将单词读入一个数组,然后请求用户输入:
while IFS= read -r; do
words+=( "$REPLY" )
done
read -r ans -p "Do stuff? [Yn] "
echo "ans: |$ans|"
问题是,Bash 立即将一个空字符串读入ans 变量,而无需等待实际的用户输入。也就是说,我得到以下输出(没有提示或延迟):
$ cat words.txt | foo
ans: ||
既然第一个read 调用已经消耗了通过管道传输到STDIN 的所有内容,为什么第二个read 调用返回而没有实际读取任何内容?
【问题讨论】:
-
不读取任何内容就返回是您的
while循环首先终止的方式:read在没有(完整)行可读取时具有非零退出状态。 -
由于第一个
read调用已经消耗了通过管道传输到 STDIN 的所有内容,因此第二个read调用没有任何内容可供读取! -
@WilliamPursell - 我的意思是,这种情况和对终端的
read调用(没有输入重定向)有什么区别?在终端read呼叫中,也没有什么可阅读的,直到我输入一些内容并按回车键。那么为什么read等待我对该电话的输入而不是在这里? -
@mklement0 感谢您指出这一点!是的,^d 不会关闭标准输入。 ^d 导致 tty 刷新其输入缓冲区,这(如果为空)导致
read(系统调用)返回 0,这反过来又使read(bash 内置)返回 0。 -
@WilliamPursell:感谢您的反馈;我已经添加了一个更详细的评论版本作为我的答案的脚注(顺便说一句:你的意思是“让
read(内置bash)返回[设置退出代码]1” ,而不是 0)。