Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

*nix user permissions are really simple, but things can get messy when you have to take in account all the parent directory access before reaching a given file. How can I check if the user has enough privileges? If not, then which directory is denying access?

For example, suppose a user joe, and the file /long/path/to/file.txt. Even if file.txt was chmoded to 777, joe still has to be able to access /long/, and then /long/path/ and then /long/path/to/ before. What I need is a way to automatically check this. If joe does not have access, I would also like to know where he has been denied. Maybe he can access /long/, but not /long/path/.

share|improve this question
up vote 10 down vote accepted

You can use bash to do this.

$ cat check-permissions.sh
# Handle non-absolute paths
if ! [[ "$file" == /* ]] ; then
dirname "$file" | tr '/' $'\n' | while read part ; do
    # Check for execute permissions
    if ! [[ -x "$path" ]] ; then
        echo "'$path' is blocking access."
if ! [[ -r "$file" ]] ; then
    echo "'$file' is not readable."
$ ./check-permissions.sh /long/path/to/file.txt

To check this for a specific user, you can use sudo.

sudo -u joe ./check-permissions.sh /long/path/to/file.txt
share|improve this answer
sudo -u joe script . Here script is the name of the script file right? so your telling sudo to act like joe was calling the script? – tgkprog Jul 9 '13 at 14:24
Precisely. I have modified my answer to clarify that. – Evan Teitelman Jul 9 '13 at 14:31
I made a slight modification to my script to handle non-absolute paths. – Evan Teitelman Jul 9 '13 at 14:47
@EvanTeitelman With an absolute path, did you mean to initialize path to be empty? or /? – Gilles Jul 9 '13 at 20:31
@Gilles: I meant for it to be empty. In the example, path is set to /long the first time around the loop, which is correct. Should I set path to nothing explicitly (path=)? Also, thanks for simplifying out my use of tr. – Evan Teitelman Jul 9 '13 at 20:58

You can use

namei -m /path/to/really/long/directory/with/file/in

which will output all of the permissions in the path in a vertical list.


namei -l /path/to/really/long/directory/with/file/in

to list all owners and the permissions

share|improve this answer
This should be the right answer. In fact using namei <path> || exit 1 allows you to detect a permission problem much easily in a script. – lorenzog Jun 2 at 10:01

As I got from your question, you should check it for different users (not only joe), so in that case the easiest way is to recursivly check it via sudo like this:

FILE=$1 ; T_USER=$2 ;
if sudo -u $T_USER [ -r "$FILE" ] ; then
    echo "original file $1 is readable for $T_USER"
    while sudo -u $T_USER [ ! -x "$FILE" ] ; do FILE=$(dirname "$FILE") ; done
    echo "only $FILE is readable for $T_USER"


./script.sh /long/path/to/file.txt joe
share|improve this answer
Joe needs execute permissions on the directories, not read permissions. – Evan Teitelman Jul 9 '13 at 14:20
@EvanTeitelman yes, you're right. Fixed. – rush Jul 9 '13 at 14:29
@rush I tried to test it using the following file: /root/test/test.txt (permissions are 0755, 0700, and 0777). I issued ./script.sh /root/test/test.txt joe and it echoed original file /root/test/test.txt is readable for joe. Also, while trying this I misstyped the test dir: ./script.sh /root/tst/test.txt joe, and it echoed original file /root/tst/test.txt is readable for joe. Did I missed something? – Metalcoder Jul 10 '13 at 17:46
@Metalcoder sorry, it's my fault. There was one extra exclamation. It's removed now, you can try it one more time, it should work fine now. – rush Jul 10 '13 at 17:50
@rush it worked! That extra exclamation negates the result of -r $FILE, right? – Metalcoder Jul 10 '13 at 18:10

Here's my attempt at providing this functionality. I've opted to use stat, a while loop, and dirname.

I've created this script, walkdir.bash:


while [ "x$cwd" != x/ ]; do
  info=`stat "$cwd" |grep "Access: ("`
  printf "%s : %s\n" "$info" "$cwd"

  cwd=`dirname "$cwd"`;

You run it like so:

$ walkdir.bash "/home/saml/blog/vmware_networking_tutorial/url.txt"
Access: (0664/-rw-rw-r--)  Uid: (  500/    saml)   Gid: (  501/    saml) : /home/saml/blog/vmware_networking_tutorial/url.txt
Access: (0775/drwxrwxr-x)  Uid: (  500/    saml)   Gid: (  501/    saml) : /home/saml/blog/vmware_networking_tutorial
Access: (0775/drwxrwxr-x)  Uid: (  500/    saml)   Gid: (  501/    saml) : /home/saml/blog
Access: (0700/drwx------)  Uid: (  500/    saml)   Gid: (  501/    saml) : /home/saml
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root) : /home
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.