2015-05-18 48 views
1

我需要使用仅在运行时已知的值为find建立参数列表。我试图用数组来做到这一点。使用数组构建参数列表

下面是使用硬编码值的简化版本。当我回应这个命令时,它看起来是正确的(当我手动运行它时,它会做我期望的)。当它进入for-loop时,它似乎在运行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文件。

+1

引用您的变量。 (例如''$ {args [@]}“',”$ f“等)。也不要像这样读取find的输出。 http://mywiki.wooledge.org/DontReadLinesWithFor http://mywiki.wooledge.org/BashFAQ/001 –

+0

请勿转义引号。 – Barmar

回答

3

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

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

然后,你需要把引号${args[@]}告诉扩大数组的时候,它应该重新报价它们的外壳:

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

谢谢。我遇到了另一个问题,并将其添加到问题中,而不是将其粘贴在此评论中,因为它允许更好的格式。 – user1011471

+0

当您使用'-o'时,您需要在每个分支中执行一个操作。我已经解决了将所有内容放在括号内的答案,以便将它们分组。 – Barmar

+0

嗯。实际上,所有参数的参数并不适用于我,但只是在' - iname'子句的旁边。但是提到这些零件的另一个答案消失了...... – user1011471

1

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