有没有办法确定脚本是否正在等待标准输入,并在检测到时导致命令退出?
下面是一个例子,我正在执行的命令需要很长时间才能运行,但它也会在开始 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 读取。其他平台也有类似的程序(例如dtrace
,ktrace
或truss
)。
yes
通过将输出提供给相关命令,您可能能够完全避免该问题。
答案4
如果您正在编写脚本:bash 的read
内置命令采用超时选项:
read -p prompt -t 5 var # 5s timeout
如果没有,您可以使用expect
,或者仅仅yes
,来伪造用户交互。