bash命令替换:在单引号中使用通配符查找命令

时间:2012-05-09 03:01:38

标签: bash quotes command-substitution

我想动态构造一个“find”命令,看看它是否返回任何内容。

这是最小化的例子。在包含文件的目录中,

find . -name '*'

当然会返回文件。但

VAR="find . -name '*'"
$VAR

什么都不返回。看起来像是引用解释的问题。但为什么呢?

(真实情况是我想看看是否存在具有特定前缀的文件。所以我打算使用-name '${MYPREFIX}*',捕获$()内的输出,并测试结果字符串是否为空。)

道歉,如果这是微不足道的。我确实花了很多时间找到答案,但我发现的所有案例都有些不同。通常,问题是shell在查找命令时应该扩展通配符。在这里,shell没有做任何过早的扩展,但也没有找到,也许是因为find接收文字引号?感谢您的任何见解。

2 个答案:

答案 0 :(得分:2)

eval $VAR

eval会将$VAR的值重新解释为带参数的命令。

警惕:eval是一种强大但危险的机制。

答案 1 :(得分:1)

我建议尽可能不使用eval。在这种情况下,如果您确实需要在执行变量之前将命令存储在变量中,我建议使用数组,然后将其作为"${cmd_array[@]}"调用:

var=(find . -name "${prefix}*")  # This stores the elements of the command as an array
result=$("${var[@]}")  # This executes the command and stores its output in $result

请注意,您还可以动态构造find命令:

patterns=()  # start with an empty list of patterns
for prefix in $prefix_list; do
    patterns+=(-o -name "${prefix}*")  # add each prefix to a list of find patterns
done
patterns=("${patterns[@]:1}") # Use array slicing to remove the first "-o"
result=$(find . "${patterns[@]}")

根据您的使用方式,将查找命令包装在bash函数中也可能有帮助:

find_prefix() {
    find . -name "${1}*"
}
result=$(find_prefix "$prefix")