2015-05-18 44 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)即可獲取所有元素。