42

我正在编写一个 POSIX shell 脚本,它可能会也可能不会像 in 那样以foo.sh < test.txt非交互方式接收来自 stdin 的输入。

如何检查 stdin 上是否有任何内容,以避免停止while read -r line...

4

4 回答 4

69

If I get the question right, you may try the following:

#!/bin/sh
if [ -t 0 ]; then
    echo running interactivelly
else
    while read -r line ; do
        echo $line
    done
fi
于 2010-03-16T18:02:29.830 回答
8

从字面上回答这个问题(但不是你真正想要的):read -t 0

超时,零秒。

  1. 这是一个竞争条件,取决于左侧何时准备好提供数据。-t 5即使有问题,您也可以在抖动系统上指定。
  2. read -t在 SUSv3 中没有标准化。它在 BSD sh、bash、zsh 中。它不在 ksh 或 dash 中。

所以你不能只使用 #!/bin/sh 并期望拥有它。

基本问题是,即使 stdin 现在没有任何内容,也不意味着不会很快出现。调用程序通常会使标准输入连接到终端/无论如何,因此无法判断需要什么。

因此,要从字面上回答您的问题,您可以这样做,但实际上您的选择是:

  1. 测试标准输入是否为 tty:[ -t 0 ]
  2. 使用 argv 控制行为
于 2010-03-16T18:52:32.507 回答
7

您可以轻松实现与“cat”命令类似的行为,即从提供的文件列表中读取,或者如果未提供,则从标准输入中读取。

虽然你可能不会使用这个想法,但我认为这篇 Linux Journal 文章对你来说会很有趣http://www.linuxjournal.com/content/determine-if-shell-input-coming-terminal-or-pipe

:-)

于 2010-03-16T18:06:24.307 回答
1

如果您不想以交互方式运行脚本,请使其将输入文件作为参数,而不是使用stdin. 一些程序使用标志或特殊文件名来指示它们应该从标准输入而不是文件中获取输入;这种情况下,您可以在必要时处理命令行操作。

如果你想让你的脚本接受标准输入,为什么不让它是交互式的(或者至少表现得像其他 POSIX 工具)?

于 2010-03-16T17:56:20.077 回答