如何在Shell变量中传递多个参数给find命令
在Bash中正确存储并使用find命令的参数
要实现把find的参数存在变量里,同时等价于命令行直接输入find -name "a*"的效果,有两种可行方案:
方案一:使用Bash数组(推荐)
Bash数组可以完美保留每个参数的边界,不会错误展开通配符或解析引号,是最安全可靠的方式:
# 定义存储参数的数组,每个参数作为数组的一个元素 args=(-name "a*") args2=(-name "a*" -o -name "b*") # 执行find命令时,用"${数组名[@]}"的方式展开数组 find . "${args[@]}" find . "${args2[@]}"
这种方式下,"${args[@]}"会将数组的每个元素原样传递给find,完全等价于在命令行直接输入find . -name "a*",通配符会由find自己解析,而不是被Bash提前展开。
方案二:使用eval(不推荐,仅适用于可控参数)
如果参数完全由你自己控制,不会包含恶意内容,也可以用eval重新解析命令行,让引号生效:
args='-name "a*"' eval find . $args
eval会重新处理整个命令字符串,把引号正确解析,让find收到-name a*这个参数。但要注意,若参数来自不可信来源,eval可能会执行恶意命令,所以尽量避免使用。
为什么之前的方法无效?
- 直接用
args='-name a*'再执行find $args:Bash会先展开通配符a*,把它替换成当前目录下匹配的文件名(比如apple),导致find实际收到的参数是-name apple。 - 用
args='-name "a*"'再执行find $args:Bash会把"a*"作为一个完整的字符串传递给find,此时find会查找文件名以双引号开头的文件,因为引号是参数的一部分,没有被Shell解析。
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

