Bash变量展开引号问题:如何正确传递参数给find命令
解决find命令递归查找C/C++文件的参数引号问题
问题描述
我尝试在脚本中递归查找C语言源文件和头文件,同时避免匹配当前目录下的文件。设置了如下变量:
FILE_MATCH_LIST='"*.c","*.cc","*.cpp","*.h","*.hh","*.hpp"' FILE_MATCH_REGEX=$(echo "$FILE_MATCH_LIST" | sed 's/,/ -o -name /g') FILE_MATCH_REGEX="-name $FILE_MATCH_REGEX"
该变量最终生成了符合预期的字符串:
+ FILE_MATCH_REGEX='-name "*.c" -o -name "*.cc" -o -name "*.cpp" -o -name "*.h" -o -name "*.hh" -o -name "*.hpp"'
但调用find命令时出现两种问题:
- 给变量加引号调用,整个参数会被单引号包裹,导致find报“unknown predicate”错误:
files=$(find $root_dir "$FILE_MATCH_REGEX" | grep -v $GREP_IGNORE_LIST) + find [directory] '-name "*.c" -o -name "*.cc" -o -name "*.cpp" -o -name "*.h" -o -name "*.hh" -o -name "*.hpp"'
- 不加引号调用,每个文件名模式会被单引号包裹双引号,导致find查找带引号的字符串而非匹配文件:
files=$(find $root_dir $FILE_MATCH_REGEX | grep -v $GREP_IGNORE_LIST) + find [directory] -name '"*.c"' -o -name '"*.cc"' -o -name '"*.cpp"' -o -name '"*.h"' -o -name '"*.hh"' -o -name '"*.hpp"'
这些单引号的来源不明,请问如何解决该引号问题,正确将参数传递给find命令?
解决方案
方法1:使用数组存储find参数(推荐)
Shell数组能正确保留每个参数的边界,不会出现引号解析混乱的问题。修改变量定义为数组:
# 直接定义数组,每个文件模式作为独立元素 FILE_PATTERNS=("*.c" "*.cc" "*.cpp" "*.h" "*.hh" "*.hpp") # 构建find的参数数组 find_args=() for pattern in "${FILE_PATTERNS[@]}"; do if [ ${#find_args[@]} -eq 0 ]; then find_args+=(-name "$pattern") else find_args+=(-o -name "$pattern") fi done # 调用find命令,数组展开时必须加双引号 files=$(find "$root_dir" "${find_args[@]}" | grep -v "$GREP_IGNORE_LIST")
这样每个-name和对应的模式都是独立参数,find能完全正确解析。
方法2:去掉变量中的多余引号,结合eval解析(谨慎使用)
修改初始变量,移除不必要的双引号,再生成参数串,最后用eval解析命令:
# 初始列表不带引号 FILE_MATCH_LIST='*.c,*.cc,*.cpp,*.h,*.hh,*.hpp' # 替换逗号为 -o -name FILE_MATCH_REGEX=$(echo "$FILE_MATCH_LIST" | sed 's/,/ -o -name /g') # 拼接前缀 FILE_MATCH_REGEX="-name $FILE_MATCH_REGEX" # 使用eval重新解析命令字符串(仅当变量内容完全可控时使用,避免注入风险) files=$(eval find "$root_dir" $FILE_MATCH_REGEX | grep -v "$GREP_IGNORE_LIST")
注意:eval会重新解析整个命令字符串,若变量内容不可控,可能带来安全风险,优先使用数组方法。
原问题原因解析
原变量中包含的双引号是字符串的一部分,当变量展开时,Shell会把这些双引号当成普通字符处理:
- 加引号展开时,整个字符串被当作一个完整参数,find无法识别这个长串为合法的查询谓词;
- 不加引号展开时,Shell按空格分割参数,每个
"*.c"会被当作一个完整参数传递给-name,导致find去查找文件名包含双引号的文件。
内容的提问来源于stack exchange,提问作者Brydon Gibson
相关产品推荐
相关产品推荐

