使用数组构建参数列表

时间:2015-05-18 20:41:34

标签: arrays bash

我需要使用仅在运行时已知的值为find建立参数列表。我正在尝试使用数组来执行此操作。

以下是使用硬编码值的简化版本。当我回显出命令它似乎是正确的(当我手动运行它时,它做了我所期望的)。当它进入for循环时,它似乎正在运行find(因为对于其他用户拥有的目录,我可以看到与Permission denied相同的错误,就像我手动运行时一样)。但是在for循环中,它不会回显出手动运行找到的任何.txt文件。

我做错了什么?

#!/bin/bash

args=(/tmp -iname \"*.txt\")

#args+=(-o -iname \"*.jpg\")

echo command will be: find ${args[@]}
for f in $( find ${args[@]} ); do
    echo found $f
done

下面接受的答案正确地确定了问题。但是,如果我添加一个额外的-iname子句,我的脚本会“忽略”除了最后一个,如下所示:

#!/bin/bash

args=($1)
args+=(-maxdepth $2)
args+=(-iname "*$3")
args+=(-o -iname "*$4")
echo command will be: find "${args[@]}"

find "${args[@]}" -print 2>/dev/null | while read -r f; do
    echo found "$f"
done

例如,当使用/home/me 2 .jpg .png调用时,这正确地表示该命令将为find /home/me -maxdepth 2 -iname *.jpg -o -iname *.png,但之后我的脚本仅回显它找到的.png个文件。

2 个答案:

答案 0 :(得分:3)

你不应该逃避引号。这将使它们成为文字,因此它将尝试查找名称实际上以双引号开头和结尾的文件。

args=(/tmp -iname "*.txt")

然后你需要在${args[@]}周围加上引号,告诉shell在扩展数组时它应该重新引用它们:

find "(" "${args[@]}" ")" -print | while read -r f
do
    echo found "$f"
done

答案 1 :(得分:1)

Bash4可以使用shopt -s globstar递归地扩展globs 只需使用array=(/tmp/**/*.txt)即可获取所有元素。