bash命令替换冻结脚本(输出太长?) - 如何应对

时间:2017-07-27 19:43:39

标签: bash command output freeze substitution

我有一个包含这样一行的bash脚本:

matches="`grep --no-filename $searchText $files`"

换句话说,我将grep的结果赋给变量。

我最近发现这行代码似乎有一个漏洞:如果grep发现了太多结果,那就很烦人地冻结了执行。

首先,如果有人能够确认过多的输出(以及确切的构成过多)是命令替换的已知危险,请为我提供一个可靠的链接。我在网上搜索过,我能找到的最近的参考文献是this link

"除非你有充分的理由这样做,否则不要将变量设置为长文本文件的内容。"

这暗示存在危险,但非常不足。

第二,是否有一个已知的最佳做法来应对此问题?

我真正想要的行为是命令替换中的过多输出 生成一个很好的人类可读错误消息,后跟一个错误退出代码,以便我的脚本将终止而不是冻结。 (注意:我总是用" set -e"作为初始行之一)运行我的脚本。我有什么方法可以解决这个问题吗?

目前,我所知道的唯一解决方案是一个hack,sorta仅适用于我的情况:我可以使用--max-count选项限制grep的输出。

1 个答案:

答案 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准备好使用它时才写一行(并且如果已经生成的输出多于可以存储的输出,则会阻塞而不需要继续读取输入相对较小的管道缓冲区) - 所以你不需要的名字甚至不会在第一时间生成,并且不需要分配内存或以任何其他方式处理它们