代码之家  ›  专栏  ›  技术社区  ›  l0b0

如何检查stdin是来自终端还是shell脚本中的管道?

  •  28
  • l0b0  · 技术社区  · 15 年前

    我正在编写一个posix shell脚本,该脚本可能会也可能不会像中那样从stdin接收输入。 foo.sh < test.txt ,非交互。

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

    4 回复  |  直到 6 年前
        1
  •  44
  •   dmedvinsky    15 年前

    如果我答对了问题,您可以尝试以下方法:

    #!/bin/sh
    if [ -t 0 ]; then
        echo running interactivelly
    else
        while read -r line ; do
            echo $line
        done
    fi
    
        2
  •  8
  •   cjds    15 年前

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

    超时,零秒。

    1. 这是一种比赛条件,取决于左侧何时准备好提供数据。您可以指定 -t 5 但在一个打击系统上,即使这样也存在问题。
    2. read -t 在SUSV3中没有标准化。它位于BSD SH、BASH、ZSH。它不在Ksh或Dash中。

    所以你不能只用!/垃圾桶/垃圾桶,希望有这个。

    最基本的问题是,即使现在在stdin上什么都没有,这并不意味着不会很快出现。调用一个程序通常会使stdin与终端/任何东西保持连接,因此无法知道需要什么。

    所以,从字面上回答你的问题,你可以这样做,但实际上你的选择是:

    1. 测试stdin是否为tty: [ -t 0 ]
    2. 使用argv控制行为
        3
  •  6
  •   darkturo    15 年前

    您可以很容易地实现类似于“cat”命令的行为,即从提供的文件列表中读取,或者如果没有提供,则从stdin中读取。

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

    -)

        4
  •  1
  •   Carl Norum    15 年前

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

    如果您希望脚本接受标准输入,为什么不让它成为交互式的(或者至少像其他POSIX工具一样工作)?