This will happen if your user doesn't have enough permissions on /home/hejhej
to list its contents.
When you run:
sudo ls -d /home/hejhej/*/
It is your shell that tried to do filename globbing. If it can't read that directory, it can't expand anything. So the literal string /home/hejhej/*/
is left as is, and passed as an argument to the ls
run by root
via sudo
. It appears you don't have a directory called *
in that directory, so ls
fails.
You need the shell started by sudo
to do the globbing here. One option might be:
sudo sh -c 'ls -d /home/hejhej/*/'
If you want the folder to search to contain a shell variable, then the '
hard quotes won't do - this prevents your shell from globbing (good) but also prevents variable expansion by your shell (bad here). You should use double-quotes ("
) instead so that variable expansion is done by your shell:
sudo sh -c "ls -d /home/$username/*/"
If you want to capture the ouput of that command into a variable, prefer the $()
form of command substitution rather than backticks (`
) - easier for quoting:
result=$(sudo sh -c "ls -d /home/$username/*/")
Now if $username
can contain spaces (say username="hello world"
), what is above won't work - the root shell will see two "tokens" (/home/hello
and world/*/
). You can fix that with another layer of quotes:
result=$(sudo sh -c "ls -d /home/'$username'/*/")
Given how the quotes are nested, this will not prevent your shell from expanding $username
, but will enable the root shell to glob correctly on the single pattern /home/hello world/*/
.
Now, this is still not perfect. You'll have a hard time dealing with issues if that glob matches more than one directory, or if the directory matched contains spaces. But at this point I'd advise you to:
- Read this advice: Why you shouldn't parse the output of ls?
- Make a proper script run by root to handle finding the appropriate directory - one-liners are fine if they're short and easy to read. Once things get too complex, writing a proper script is a win in the long run.
That being said, if you want a list of directories from another user's home into an array, the following (bash specific I think) should do it, without the problems of parsing ls
, and should handle spaces in files and directories:
while read -r -d $'\0' dir ; do
array+=("$dir")
done < <(sudo find "/home/$username" -maxdepth 1 -mindepth 1 -print0)