I have a file path.. Is there any single command to see the file/directory permissions of all the intermediate directories in the path..?
6 Answers
Linux comes with the namei
command which is mainly useful to display symbolic links in paths, but can also show ownership.
$ namei -nom ~
f: /home/gilles
drwxr-xr-x root root /
drwxr-sr-x root staff home
drwxr-xr-x gilles gilles gilles
Otherwise, here's a way to iterate over the successive directories containing a given file (not the only one, as other answers on this page illustrate) and list their contents.
d=$PWD; set /;
while [ -n "$d" ]; do set -- "$@" "$d/"; d=${d%/*}; done;
ls -ld "$@"
Note that this listing can be a little misleading in the presence of symbolic links. For example, if /foo/bar
is a symbolic link to /hello/world
which is itself a symbolic link to /one/two
, and all of /foo
, /hello
and /world
are world-readable (say mode 755) but /hello
is not readable to user Alice, then Alice won't be able to reach /foo/bar
, yet the listing above will show only world-readable directories.
Here are two oneliners. One ls
call per path component:
$ (IFS=/; set -f -- $PWD; for arg; do path="${path%/}/$arg"; ls -dal "$path"; done)
Output:
# drwxr-xr-x 31 root admin 1122 4 Nov 22:08 /
# drwxr-xr-x 9 root admin 306 3 Nov 17:36 /Users
# drwxr-xr-x+ 67 janmoesen staff 2278 7 Nov 14:46 /Users/janmoesen
# drwxr-xr-x+ 53 janmoesen staff 1802 4 Nov 22:07 /Users/janmoesen/Sites
# drwxr-xr-x 28 janmoesen staff 952 7 Nov 15:01 /Users/janmoesen/Sites/example.com
With just one call to ls
with all paths:
$ (IFS=/; set -f -- $PWD; for arg; do path="${path%/}/$arg"; paths+=("$path"); done; ls -dal "${paths[@]}")
Output:
# drwxr-xr-x 31 root admin 1122 4 Nov 22:08 /
# drwxr-xr-x 9 root admin 306 3 Nov 17:36 /Users
# drwxr-xr-x+ 67 janmoesen staff 2278 7 Nov 14:46 /Users/janmoesen
# drwxr-xr-x+ 53 janmoesen staff 1802 4 Nov 22:07 /Users/janmoesen/Sites
# drwxr-xr-x 28 janmoesen staff 952 7 Nov 15:01 /Users/janmoesen/Sites/example.com
-
Thanks for the correction, Gilles! Could you give an example of how globbing can mess up the
set --
without-f
? I tried with a directorya[bar]
on the same level as directoriesab
,aa
andar
, but did not succeed. (EDIT: Succeed in failing, that is. I want to know how it goes wrong.) Commented Nov 10, 2011 at 7:43
#!/bin/bash
(( $# )) || set -- "$PWD"
IFS='/'
for _arg; do
if ! [[ -e "${_arg}" ]]; then
printf '%s\n' "${_arg} does not exist!"
exit 1
fi
read -ra _dirs <<< "${_arg}"
(( _length = ${#_dirs[@]} + 1 ))
for (( _offset = 2 ; _offset < _length ; _offset++ )); do
_current_dir="${_dirs[*]::_offset}"
_perms=$(ls -ld "${_current_dir}" | awk '{ print $1" "$3" "$4 }')
printf '%s %s\n' "${_perms}" "${_current_dir}"
done
done
I don't know of a short way to do so. For this task I use a shell script, you may find useful, too:
#!/bin/ksh
if [ $# -eq 0 ]
then
set "$PWD"
fi
for path in "$@"
do
while true
do
ls -ld "$path"
if [ -z "$path" -o "$path" = . -o "$path" = / ]
then
break
fi
path=$(dirname "$path")
done
done
EDIT: Using an until
loop omits the need for the break ...
#!/bin/ksh
[ $# -eq 0 ] && set "$PWD"
for path
do
until test -z "$path" -o "$path" = . -o "$path" = /
do
ls -ld "$path"
path=$(dirname "$path")
done
done
-
Your script will break on certain paths with special characters. Commented Nov 7, 2011 at 13:36
-
ok - added some more quotes. But for such rare occasions and no changes made to anything I lived with that.– ktfCommented Nov 7, 2011 at 15:56
-
1It would be simpler to leverage
IFS
for splitting on/
, like janmoesen does. Commented Nov 7, 2011 at 23:24
Not so complicated, but this would help you I guess.
find . -type d -exec ls -lrt {} \;
List permissions of every directory in a directory path (up or down)
alias dirls='_dirls() { path="$(realpath $1)";_path="";for i in " " ${path//\// }; do _path="$_path$i/"; ls -ld $_path; done; unset _path; };_dirls'
alias dirls2='_dirls2() { path="$(realpath $1)"; while [[ "$path" != "/" ]]; do ls -ld "$path"; path="$(dirname "$path")"; done; ls -ldh /; };_dirls2'
eg:
# dirls /usr/local/bin
dr-xr-xr-x. 18 root root 236 Nov 11 19:01 /
drwxr-xr-x. 15 root root 181 Dec 7 11:50 /usr/
drwxr-xr-x. 15 root root 205 Nov 22 14:06 /usr/local/
drwxr-xr-x. 2 root root 4096 Dec 5 12:19 /usr/local/bin/
# dirls2 /usr/local/bin
drwxr-xr-x. 2 root root 4096 Dec 5 12:19 /usr/local/bin
drwxr-xr-x. 15 root root 205 Nov 22 14:06 /usr/local
drwxr-xr-x. 15 root root 181 Dec 7 11:50 /usr
dr-xr-xr-x. 18 root root 236 Nov 11 19:01 /