我有一个包含这样一行的bash脚本:
matches="`grep --no-filename $searchText $files`"
换句话说,我将grep的结果赋给变量。
我最近发现这行代码似乎有一个漏洞:如果grep发现了太多结果,那就很烦人地冻结了执行。
首先,如果有人能够确认过多的输出(以及确切的构成过多)是命令替换的已知危险,请为我提供一个可靠的链接。我在网上搜索过,我能找到的最近的参考文献是this link:
"除非你有充分的理由这样做,否则不要将变量设置为长文本文件的内容。"
这暗示存在危险,但非常不足。
第二,是否有一个已知的最佳做法来应对此问题?
我真正想要的行为是命令替换中的过多输出 生成一个很好的人类可读错误消息,后跟一个错误退出代码,以便我的脚本将终止而不是冻结。 (注意:我总是用" set -e"作为初始行之一)运行我的脚本。我有什么方法可以解决这个问题吗?
目前,我所知道的唯一解决方案是一个hack,sorta仅适用于我的情况:我可以使用--max-count选项限制grep的输出。
答案 0 :(得分:1)
理想情况下,您不应该将未知长度的数据捕获到内存中;如果您根据需要阅读它,那么grep
将等待内容准备好使用。
那是:
while IFS= read -r match; do
echo "Found a match: $match"
# example: maybe we want to look at whether a match exists on the filesystem
[[ -e $match ]] && { echo "Got what we needed!" >&2; break; }
done < <(grep --no-filename "$searchText" "${files[@]}")
这样,grep
只在read
准备好使用它时才写一行(并且如果已经生成的输出多于可以存储的输出,则会阻塞而不需要继续读取输入相对较小的管道缓冲区) - 所以你不需要的名字甚至不会在第一时间生成,并且不需要分配内存或以任何其他方式处理它们