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

时间:2010-03-16 17:43:44

标签: posix sh

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

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

4 个答案:

答案 0 :(得分:44)

如果我的问题正确,您可以尝试以下方法:

#!/bin/sh
if [ -t 0 ]; then
    echo running interactivelly
else
    while read -r line ; do
        echo $line
    done
fi

答案 1 :(得分:8)

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

超时,零秒。

  1. 这是一种竞争条件,取决于左侧是否准备好提供数据。你可以指定-t 5但是在一个颠簸的系统上,即使这是有问题的。
  2. read -t在SUSv3中未标准化。它在BSD sh,bash,zsh中。它不是ksh或破折号。
  3. 所以你不能只使用#!/ bin / sh并期望拥有它。

    基本问题是,即使现在stdin上没有任何内容,这并不意味着不会很快。调用一个程序通常会将stdin连接到终端/无论什么,所以没有办法告诉你需要什么。

    所以,要按字面意思回答你的问题,你可以做到,但在实践中你的选择是:

    1. 测试stdin是否为tty:[ -t 0 ]
    2. 使用argv控制行为

答案 2 :(得分:6)

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

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

: - )

答案 3 :(得分:1)

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

如果您希望脚本采用标准输入,为什么不想让它成为交互式(或者至少表现得像其他POSIX工具一样)?