Script that uses variable username in find command
I'm trying to write a script that lists the absolute paths of all of a given user's home files and directories, recursively, and writes all of them to an array. Currently, I'm using find like so ...
user="foobar" usersHomeFiles=( $(find ~$user -printf "%p\\n") )
However, when I execute this script it tells me ...
find: `~foobar': No such file or directory
Even though foobar is a valid user with a home directory. I even get the same error running it with user="root". Any ideas how I could fix this so the find command works in my script?
This happens because in bash "tilde expansion" happens before "parameter expansion". So tilde expansion attempts to find user "$user", this fails and the tilde remains unchanged. Next comes "parameter expansion" substituting "$user" with "foobar". See bash(1) "EXPANSION" section.
One way to do this is with "eval", like this:
user_home=`eval "echo ~$user"`
Another is directly querying the passwd database, like this:
user_home=`getent passwd "$user" | cut -d: -f6`
However, note that your array assignment will break if user home directory contains filenames with spaces or tabs.
You can read them more reliably with "readarray", like this:
readarray -t usersHomeFiles < <(find "$user_home")
Tilde expansion occurs prior to parameter expansion, so the tilde ~$user is left as-is. You'll need something like
userHome=$( eval "echo ~$user" ) userHomeFiles=( $( find "$userHome" -print '%p\n' ) )
although I hope someone will post an eval-free solution. This is not safe unless you are absolutely sure of the contents of user.