Question

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?

Était-ce utile?

La solution

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 \)

Autres conseils

  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"
    
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top