2013-05-02 84 views
0

我正在嘗試編寫一個腳本,該腳本遞歸地列出給定用戶的所有主文件和目錄的絕對路徑,並將它們全部寫入數組。目前,我使用find這樣的...在find命令中使用變量用戶名的腳本

user="foobar" 
usersHomeFiles=($(find ~$user -printf "%p\\n")) 

然而,當我執行這個腳本,它告訴我...

find: `~foobar': No such file or directory 

即使foobar是一個主目錄中的有效用戶。我甚至得到與user="root"一樣的錯誤。任何想法我可以解決這個問題,所以find命令在我的腳本中工作?

+0

使用的zsh,而不是bash的 – Kevin 2013-05-02 18:24:54

+0

[這個答案](http://stackoverflow.com/a/14931757/1126841)至一個相關的問題可能會有所幫助,雖然它與我下面的答案一樣提出了相同的警告。 – chepner 2013-05-02 18:27:08

回答

2

這是因爲在bash「波浪線擴展」發生在「參數擴展」之前。因此,代字符擴展試圖找到用戶「$ user」,這會失敗並且代字號保持不變。接下來是「參數擴展」,用「foobar」代替「$ user」。請參閱bash(1)「EXPANSION」部分。要做到這一點

一種方法是用「EVAL」,像這樣:

user_home=`eval "echo ~$user"` 

另一種是直接查詢密碼數據庫,就像這樣:

user_home=`getent passwd "$user" | cut -d: -f6` 

但是請注意,您的數組賦值如果用戶主目錄包含帶空格或製表符的文件名,將會中斷。

你可以用 「readarray」 更可靠地閱讀它們,就像這樣:

readarray -t usersHomeFiles < <(find "$user_home") 
2

在參數擴展之前發生梯級擴展,因此波形~$user保持原樣。雖然我希望有人將發佈一個eval - 免費的解決方案,你需要像

userHome=$(eval "echo ~$user") 
userHomeFiles=($(find "$userHome" -print '%p\n')) 

。這是不安全的,除非你絕對確信user的內容。

+0

爲了避免eval,難道你不會做像userhome = $(回聲「〜$ {user}」)...... nope,只是試過了,這是行不通的。 – senorsmile 2013-05-02 18:35:47

0

您可能需要幾個選項添加到您find命令,即在哪兒找到的開始從搜索和-name標誌即路徑:

$(find /home/$user -name "*" -printf "%p\\n")