Bash script to test if a given user can read a directory and all files inside?
Asked Answered
P

2

7

I need to test in a bash script if a given user can read a given directory with all files and sub-directories inside. The script runs as root.

Assuming the given user name is $user and the directory to test is $dir I added the following line to the script

su -m $user -c "test -r $dir && test -x $dir"
if [ $? -ne ]; then
   echo "$dir is not readable or executable"
fi

Would you suggest correct or improve it?

Phenomenon answered 24/10, 2013 at 14:52 Comment(0)
M
4

You could simply say:

su -m $user -c "find $dir >/dev/null 2>&1 || echo $dir is not readable or executable"

This would generate the not readable or executable message if any files/directories within $dir are not readable.

find $dir would return an error code of non-zero if it's not able to read any file.


EDIT: A more complete (or reliable) way of finding all directories/files that are not readable would be to say:

find . \( -type d -perm /u+r -o -type d -perm /u+x -o -type f -perm /u+r \)
Madelainemadeleine answered 24/10, 2013 at 14:55 Comment(1)
It looks like "find" returns 0 even if some files are not readable. How can I test that all files inside $dir are readable by $user ?Phenomenon
I
4
  1. There seems to be something missing here:

    if [ $? -ne ]; then
    

    Surely you meant to write:

    if [ $? -ne 0 ]; then
    

    But in fact the test is not necessary because you can use ||:

    su -m $user -c "test -r $dir && test -x $dir" ||
    echo "$dir is not readable or executable"
    
  2. Instead of:

    test -r $dir && test -x $dir
    

    you can use the -a option (logical and) to test:

    test -r $dir -a -x $dir
    
  3. Where does the variable $user come from? Is it trusted? If not, there'll be trouble if someone supplies a value like root;. Even if you are sure that $user is OK in this case, it's still worth getting into the habit of quoting your variables in shell scripts: here you'd be safe if you had written:

    su -m "$user" -c "..."
    
  4. There's a similar problem if $dir is untrusted — someone might supply a value like /; sh. But in this case quoting it like this won't work:

    su -m "$user" -c "test -r '$dir' -a -x '$dir'"
    

    because someone might supply a value like /'; sh; echo '. Instead, you need to pass the quoted "$dir" to the subshell as a parameter which you can then refer to safely using $1:

    su -m "$user" -c 'test -r "$1" -a -x "$1"' -- "$dir"
    
Idiom answered 24/10, 2013 at 15:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.