如果流在BASH中为空,则停止从STDOUT读取



我正在用BASH创建一个脚本(myscript.sh),它从STDOUT(通常是来自cat的数据流)或文件中读取数据流并输出数据流(太棒了!),如下所示:

猫myfile.txt美元

hello world !

$cat myfile.txt | myscript.sh

hello world !

美元myscript.sh myfile.txt

hello world !

但我也希望以下行为:如果我调用脚本没有参数,我希望它输出一个简短的帮助:

myscript.sh美元

我是帮助:我只是打印你说的话。

==问题==

问题是我像这样捕获数据流:

if [[ $# -eq 0 ]]; then
stream=$(cat <&0)

elif [[ -n "$stream" ]]; then

echo "I am the help:  I just print what you say."
else
echo "Unknown error."
fi

当我调用脚本时,没有像这样的参数:美元myscript.sh

应该打印"help"部分,但它只是继续等待上面第2行代码中的数据流…有没有办法告诉bash,如果STDOUT没有输出,就中断并继续执行?

提前感谢。

总是有一个标准的输入流;如果没有给出参数并且没有重定向输入,则标准输入为终端。

如果您想要特殊处理,使用test -t来测试标准输入是否连接到终端。

if [[ $# -eq 0 && -t 0 ]]; then
echo "I am the help:  I just print what you say."
else
stream=$(cat -- "$@")
fi

不需要测试$#。把你的参数传递给cat;如果它得到文件名,它将从文件名中读取,否则它将从标准输入中读取。

我同意@Barmar的解决方案。

但是,最好完全避免这样一种情况,即您的程序行为取决于输入文件描述符是否是一个终端(在某些情况下,即使没有终端也会模拟终端——在这种情况下,您的脚本将只生成帮助字符串)。

您可以引入一个特殊的-参数来显式请求从stdin读取数据。这将导致更简单的选项处理和统一的脚本行为,无论环境如何。

第一个答案是帮助您自己-尝试使用bash -x myscript.sh运行脚本。里面会有很多信息对你有帮助。

如果你指定的情况,条件$# -eq 0被翻转。按照要求,你想打印帮助信息是NOT ARGUMENT ARE提供:

if [[ $# -eq 0 ]] ; then
echo "I am the help:  I just print what you say."
exit 0
fi
# Rest of you script, read data from file, etc.
cat -- "$@"

假设采用了这种方法,并且如果您想处理标准输入或文件,只需传递'-'作为参数:cat foobar.txt | myscript.sh -

最新更新