ksh:如何探测stdin?

时间:2009-03-11 16:38:15

标签: unix shell stdin ksh tty

我希望我的ksh脚本具有不同的行为,具体取决于是否有通过stdin传入的内容:

    (1) cat file.txt | ./script.ksh  (then do "cat <&0 >./tmp.dat" and process tmp.dat)
vs. (2) ./script.ksh (then process $1 which must be a readable regular file)

检查stdin以查看它是否是终端[-t 0]没有帮助,因为我的脚本是从其他脚本调用的。

如果stdin为“空”(第二种情况),执行“cat&lt;&amp; 0&gt; ./tmp.dat”检查tmp.dat的大小会挂起等待stdin的EOF。

如何检查标准输入是否为“空”?!

3 个答案:

答案 0 :(得分:3)

编辑:您正在使用HP-UX

运行

在HP-UX上测试[ -t 0 ],它似乎对我有用。我使用了以下设置:

/tmp/x.ksh:

#!/bin/ksh
/tmp/y.ksh

/tmp/y.ksh:

#!/bin/ksh
test -t 0 && echo "terminal!"

正在运行/tmp/x.ksh次打印:terminal!

您是否可以在您的平台上确认以上内容,和/或提供更准确反映您情况的备用测试设置?您的脚本最终是由cron生成的吗?


编辑2

如果绝望,如果Perl可用,请定义:

stdin_ready() {
  TIMEOUT=$1; shift
  perl -e '
    my $rin = "";
    vec($rin,fileno(STDIN),1) = 1;
    select($rout=$rin, undef, undef, '$TIMEOUT') < 1 && exit 1;
  '
}

stdin_ready 1 || 'stdin not ready in 1 second, assuming terminal'

编辑3

请注意,如果您的输入来自sortssh等,则超时可能需要很长。(所有这些程序都可以在生成任何内容之前的几秒或几分钟内生成并建立管道管道它上面的数据。)此外,当输入中没有任何内容(例如终端)时,使用大量超时可能会严重损害您的脚本。

如果可能存在大的超时问题,并且如果您可以影响脚本的调用方式,那么您可能希望强制调用者明确地指示您的程序是否应该使用stdin,通过自定义选项或标准GNUtar方式(例如script [options [ - ]] FILE ...,其中FILE可以是文件名,-表示标准输入,或者如果将-作为参数传入,则您的脚本只能从标准输入中读取。)

答案 1 :(得分:2)

此策略适用于bash,可能适用于ksh。民意调查:

#!/bin/bash
set -a

if [ "$( tty )" == 'not a tty' ]
then
    STDIN_DATA_PRESENT=1
else
    STDIN_DATA_PRESENT=0
fi

if [ ${STDIN_DATA_PRESENT} -eq 1 ]
then
    echo "Input was found."
else
    echo "Input was not found."
fi

答案 2 :(得分:0)

为什么不以更传统的方式解决这个问题,并使用命令行参数来指示数据将来自stdin?

举个例子,考虑一下:

之间的区别
  

echo foo | cat -

  

echo foo > /tmp/test.txt

     

cat /tmp/test.txt