测试正在等待标准输入的脚本

测试正在等待标准输入的脚本

有没有办法确定脚本是否正在等待标准输入,并在检测到时导致命令退出?

下面是一个例子,我正在执行的命令需要很长时间才能运行,但它也会在开始 w/o 提示之前提示输入。我想知道该命令实际上在做一些事情,而不仅仅是等待。

提供以下名为 ./demo 的脚本

#!/bin/bash

read

有没有办法检测 read 是否正在等待 stdin?比如

failifwaitingonstdin | ./demo

一旦检测到读取命令就会立即返回。

更新:

人们建议使用 expect 和 yes 之类的程序。在深入研究 yes 之后,我明白了它们如何支持这种交互方式。它们不断使用 fputs 将“y”写入 stdout。我不必无休止地这样做,只要 fputs 返回写入 stdout 的结果,我就可以简单地返回错误。

答案1

如果您对脚本和/或命令有更具体的说明,那将非常有帮助。但是,如果您想测试 stdin 来自何处,此示例脚本将为您演示:

#!/bin/bash
if [[ -p /dev/stdin ]]
then
    echo "stdin is coming from a pipe"
fi
if [[ -t 0 ]]
then
    echo "stdin is coming from the terminal"
fi
if [[ ! -t 0 && ! -p /dev/stdin ]]
then
    echo "stdin is redirected"
fi
read
echo "$REPLY"

示例运行:

$ echo "hi" | ./demo
stdin is coming from a pipe
$ ./demo
[press ctrl-d]
stdin is coming from the terminal
$ ./demo < inputfile
stdin is redirected
$ ./demo <<< hello
stdin is redirected
$ ./demo <<EOF
goodbye
EOF
stdin is redirected

答案2

在不知道您要做什么的情况下,我认为您应该编写脚本,以便始终知道它是否会要求 stdin。或者将可能需要 stdin 的内容输入到命令中,但这可能不是最好的主意。

答案3

如果您使用的是 Linux,则可以使用strace来查看进程是否正在尝试从 stdin 读取。其他平台也有类似的程序(例如dtracektracetruss)。

yes通过将输出提供给相关命令,您可能能够完全避免该问题。

答案4

如果您正在编写脚本:bash 的read内置命令采用超时选项:

read -p prompt -t 5 var # 5s timeout

如果没有,您可以使用expect,或者仅仅yes,来伪造用户交互。

相关内容