To set file permissions using the chmod
command, we can specify the permissions in either numeric mode or symbolic mode. But when we want to get the file permissions, most often with the ls -l
command, we are normally only given a printout using the symbolic mode.
There are a couple of ways to print permissions in octal mode. The first method is by using the stat
command.
1 |
$ stat -c "%a" /path/to/file |
The above will printout the octal permissions of a file. Noting more, nothing less. But if we try to use the command and pass a wildcard argument, the information would be meaningless.
1 2 3 |
$ stat -c "%a" * 755 644 |
You will not know which permissions are for which file. To include the filenames alongside with the permissions, make a slight modification to the stat
command.
1 2 3 |
$ stat -c "%a %n" * 755 foo 644 foo.c |
Now we know that file foo
has a permission of 755
and file foo.c
has a permission of 644
.
The octal permissions of the stat
command also takes care of setuid
, setgid
and sticky
bits. We can test this by printing the permissions of su
– a standard setuid
command.
1 2 |
$ stat -c "%a %A %n" $(which su) 4755 -rwsr-xr-x /bin/su |
I have written a small shell script that will make use of the ls
and awk
commands to print the octal permissions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#!/bin/sh ls -l "$@" | awk '{ i=0; for(j=0;j<=8;j++) { p=substr($1,j+2,1); i+=((p~/[rwxst]/)*2^(8-j)); if(j==2&&p~/[sS]/) i+=04000; if(j==5&&p~/[sS]/) i+=02000; if(j==8&&p~/[tT]/) i+=01000; } if(i)printf("%04o ",i); print }' |
Copy the script to a file called lso
(ls octal
), make it executable and run it like this:
1 |
$ lso /path/to/file |
Alternatively, if you are not interested in the shell script, you can opt to copy the below function to your shell initialisation file ( eg. .bashrc
or .bash_profile
) instead.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function lso () { ls -l "$@" | awk '{ i=0; for(j=0;j<=8;j++) { p=substr($1,j+2,1); i+=((p~/[rwxst]/)*2^(8-j)); if(j==2&&p~/[sS]/) i+=04000; if(j==5&&p~/[sS]/) i+=02000; if(j==8&&p~/[tT]/) i+=01000; } if(i)printf("%04o ",i); print }' } |
Run the function by calling the function name from the command line.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ lso -d /tmp ; 1777 drwxrwxrwt 5 root root 4096 Jan 11 21:51 /tmp $ stat -c "%a %n" /tmp 1777 /tmp $ lso -d $(which passwd) ; stat -c "%a %n" $(which passwd) 4755 -rwsr-xr-x 1 root root 47032 Jan 27 2016 /usr/bin/passwd 4755 /usr/bin/passwd $ lso -d $(which su) ; stat -c "%a %n" $(which su) 4755 -rwsr-xr-x 1 root root 36936 Jan 27 2016 /bin/su 4755 /bin/su |
Update (11-Jan-2017): Script updated to handle setuid
, setgid
and sticky
bits.