在 while read(stdin)循环后暂停 bash 脚本

4
我正在编写一个脚本,通过管道(stdin)接收输入,例如 (other_command | my_script)。但是,在我读取完整个stdin后,我需要暂停脚本并等待用户按下回车键。
以下是一个示例脚本。
#!/bin/bash

if [[ -t 0 ]]; then
  echo "No stdin"
else
  echo "Got stdin"
  while read input; do
    echo $input
  done
fi

echo "Press enter to exit"
read

它的工作原理如下:
$ echo text | ./script
Got stdin
text
Press enter to exit
$

它跳过了我最后的读取
然而;
$ ./script
No stdin
Press enter to exit
stops here
$

在从标准输入读取后,如何使read函数正常工作?是否有适用于Linux和OSX的解决方案?

1个回答

5

您想从用户那里读取内容。如果stdin不是用户,则必须从其他地方读取。典型的选择是当前终端(这里连接到stderr的终端,假设有一个)。

read -p "Press enter" < "$(tty 0>&2)"

默认情况下,tty在标准输入上查找tty的名称,当标准输入是管道时,显然无法正常工作。因此,我们将其重定向以使其查看标准错误流。


好的观点,但是如果像这样运行,tty会说not a tty。否则是/dev/ttys006。因此,read < "/dev/ttys006"可以工作,但不可行。 - xeor
你确定你没有在命令中漏掉一部分内容吗?"$(tty)"只是简单地执行 tty 并将结果用引号括起来。tty 会返回类似于 /dev/ttys006 的结果(根据系统/终端的不同)。所以 "$(tty)" 应该恰好是 "/dev/ttys006"。在你的终端中执行以下命令来检查:( mytty="$(tty)"; echo "tty: $mytty" ) - David C. Rankin
echo "tty" > test; sh test; echo string | sh test 在我的 OSX 和 Linux 测试中都会显示一行 /dev/ttys006 和一行 not a tty - xeor
在你的编辑中添加0>&2后,它就像魔法般地运行良好。 :) - xeor
你介意写一个简短的总结,解释一下为什么“0>&2”起作用吗?这会使答案更加完整。 - xeor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接