2010-03-16 91 views
25

我正在编写一个POSIX外壳脚本​​,它可能会或可能不会从标准输入接收输入(如foo.sh < test.txt,非交互式)。如何检查stdin上是否有任何内容,以避免在while read -r line...上停止?检测外壳脚本中标准输入内容的存在

+0

标准输出:http://stackoverflow.com/questions/911168/how-to-detect-if-my-shell-script-is-running-through-a-pipe – 2017-05-11 09:01:10

回答

39

如果我有问题的权利,你可以尝试以下方法:

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

只是向上看,这是由于stdin和捕获stdout时触发的。 (二者interactivelly运行) ./yourscript <./the_input_your_giving_your_script.txt && ./yourscript> ./what_your_script_outputs。txt – DebugXYZ 2014-06-29 05:23:03

+1

@DeShawnWilliams不,@ dmedvinsky的回答是正确的:如果在终端上打开文件描述符'n','test -tn'为true,因此'test -t 0'只检查stdin,'test -t 1 '只检查标准输出。 – bootleg 2015-05-22 07:55:09

1

如果您从不想以交互方式运行脚本,请将输入文件作为参数,而不是使用stdin。某些程序使用标志或特殊文件名来表示它们应该从标准输入而不是从文件输入;该案例可以让你在必要时处理命令行操作。

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

+4

一种常见的方式来告诉程序从标准输入读取的文件是提供'-'而不是文件名。 – Cascabel 2010-03-16 18:07:46

6

您可以轻松实现类似的行为作为“猫”的命令,即从提供的文件,或者如果列表请他们'没有提供,然后从标准输入读取。

虽然你可能不使用这种想法,我觉得这篇Linux Journal中会是很有意思的,你http://www.linuxjournal.com/content/determine-if-shell-input-coming-terminal-or-pipe

:-)

+0

嗯,从中午回复。很酷^ _^ – darkturo 2010-03-16 18:08:26

+0

该链接非常有帮助,谢谢! – hamstar 2013-08-14 21:47:35

8

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

超时,零秒。

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

所以你不能只使用#!/ bin/sh,并期待有这个。

基本的问题是,即使现在没有任何标准输入,这并不意味着不会很快。调用一个程序通常会让stdin连接到终端/无论如何,所以无法告诉需要什么。

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

  1. 测试,如果标准输入是一个tty:[ -t 0 ]
  2. 使用argv的控制行为
+1

我刚刚使用zsh进行了试验。我注意到'read -t'或等价地'read -t0'具有**非确定性**行为。所以,如你所说,避免使用它。 – Tarrasch 2013-01-01 18:25:51

+1

但是,这要与答案中使用的_test_“-t”区分开来。 – 2014-11-20 00:21:01