2013-05-02 115 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")