防止shell脚本中的参数扩展

防止shell脚本中的参数扩展

我经常需要在文件中进行递归搜索。厌倦了一直输入整个“find/grep”组合,我刚刚创建了一个包含以下行的脚本:

find . -name $1 -exec grep $2 {} + 2>/dev/null

我的想法是,我应该能够以如下方式运行它,例如:

myfind '*' hello

问题是,当'*'传递到脚本中时,脚本会将其扩展到目录中的每个文件。

我尝试引用一下$1

 find . -name '$1' -exec grep $2 {} + 2>/dev/null

然而,这会$1变成一个文字字符串。

非常感谢您能帮我找到正确的语法。我肯定遗漏了一些简单的东西。

答案1

我在这里演示了这个问题:

$ pie() { echo $1; }; pie '*'
1 2 3 4 5 file

扩大。厭扰。

但解决方案很简单。你只需要用 bash 能理解的方式引用它。我们使用双引号。它将被替换为变量内容,但不会被扩展。

$ pie() { echo "$1"; }; pie '*'
*

答案2

您需要熟悉有关 shell 变量扩展的基本规则。

NAME="start"

如果你将 $NAME 提供给 shell,它将被扩展为字符串开始

如果将字符串放在单引号中,则 shell 不会扩展单引号内的内容,因此 '$NAME' 仍为 $NAME

现在有了双引号,shell 将变量 $NAME 扩展为字符串开始但双引号会阻止所谓的文件通配。

您可能会问,文件通配是什么?

嗯,你做的

ls -l *

您期望 ls 命令列出所有文件。将 * 转换为目录中所有文件名的不是 ls,而是 shell。

现在假设你的目录中有一个名为 * 的文件,而你只想列出该文件,那么你可以使用

ls -l '*' 

或者

ls -l "*"

单引号和双引号都会阻止 shell 将 * 扩展为文件列表。

也可以通过以下方式关闭通配符

set noglob

与其将这个简单的查找字符串作为一个单独的 shell 脚本,每次使用时都需要调用一个新的 shell,更有效的方法是将其创建为一个 shell 函数 fs(find_string)

function fs ()
{
 \find . -type f -name "${1}" -exec egrep --color "${2}" {} /dev/null \;
}

相关内容