4

我希望我的 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 <&0 >./tmp.dat”检查 tmp.dat 的大小会挂起等待来自 stdin 的 EOF。

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

4

3 回答 3

4

编辑:您在 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

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

如果潜在的大超时是一个问题,并且如果您可以影响调用脚本的方式,那么您可能希望强制调用者明确指示您的程序是否应该使用标准输入,通过自定义选项或在标准GNUtar方式(例如 script [options [--]] FILE ...,其中 FILE 可以是文件名、-表示标准输入的 a 或它们的组合,如果-作为范围。)

于 2009-03-11T19:09:13.067 回答
2

此策略适用于 bash,并且可能适用于 ksh。投票'tty':

#!/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
于 2009-04-03T15:42:35.707 回答
0

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

例如,考虑以下之间的区别:

echo foo | cat -

echo foo > /tmp/test.txt

cat /tmp/test.txt

于 2009-03-26T19:27:10.873 回答