Ask Ubuntu is a question and answer site for Ubuntu users and developers. 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

There is a chmod command to set file permissions, but can I get file permissions in octal mode (such as 755) from the command line?

share|improve this question
up vote 246 down vote accepted

You can try

stat -c "%a %n" *

Replace * with the relevant directory or the exact filename that you want to examine.

From the man page of stat,

-c  --format=FORMAT
          use  the  specified  FORMAT instead of the default; output a newline after
          each use of FORMAT
%a     Access rights in octal
%n     File name


  • With files:

    $ stat -c "%a %n" ./Documents/Udev.html 
    664 ./Documents/Udev.html
  • With folders:

    $ stat -c "%a %n" ./Documents/
    755 ./Documents/


share|improve this answer
on mac os, use stat -f '%A %a %N' * (credit:…) – s2t2 Apr 15 '15 at 22:07
If you are more comfortable with ls: for f in $(ls -a); do stat -c "%a %n" $f; done; – usandfriends Jul 18 '15 at 19:00
@usandfriends looping on the output of ls is a bad idea. If you really want to use a loop you can do for f in *; do stat "%a %n" "$f"; done – Tom Fenech Feb 18 at 10:12
stat -c "%a %n" `find . -true -print` to recurse into directories. cd /etc ; stat -c "%a %n" `find . -true -print` | while read line ; do cd /mnt/broken/etc ; chmod $line ; done to copy permissions (e.g. after a runaway chmod -R accident). – SF. May 20 at 10:34

File permissions in Linux can be displayed in octal format using Linux stat command.

Just press Ctrl+Alt+T on your keyboard to open Terminal. When it opens, Navigate to the directory where you want to find the file permissions in octal mode.

stat -c '%A %a %n' *

%A Access rights in human readable form

%a Access rights in octal

%n File name

Octal numbers and permissions

You can use octal number to represent mode/permission:

r: 4
w: 2
x: 1

For example, for file owner you can use octal mode as follows. Read, write and execute (full) permission on a file in octal is 0+r+w+x = 0+4+2+1 = 7

Only Read and write permission on a file in octal is 0+r+w+x = 0+4+2+0 = 6

Only read and execute permission on a file in octal is 0+r+w+x = 0+4+0+1 = 5

Use above method to calculate permission for group and others. Let us say you wish to give full permission to owner, read & execute permission to group, and read only permission to others, then you need to calculate permission as follows: User = r+w+x = 0+4+2+1 = 7 Group= r+w+x = 0+4+2+0 = 6 Others = r+w+x = 0+0+0+1 = 1

Effective permission is 761.


share|improve this answer
The initial 0 represent special bit too: – Braiam Jul 28 '13 at 1:45

As detailed in “755”-style permissions with ‘ls’ by Adam Courtemanche on, you can create an alias lso that acts like ls -l but slightly processes the output1 to display permissions also in octal.

alias lso="ls -alG | awk '{k=0;for(i=0;i<=8;i++)k+=((substr(\$1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(\" %0o \",k);print}'"

This has a serious shortcoming, though, as techtonik points out. You cannot pass arguments to this lso alias as you would to the ls command, because they are taken as additional arguments to awk instead. Thus you cannot run lso on a specific file or directory, nor can you pass any options (like -F, or --color) to lso.

The fix is to define lso as a function rather than an alias.

lso() { ls -alG "$@" | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(" %0o ",k);print}'; }

If you're trying this out interactively in your shell, run unalias lso to remove the alias--you can do that either before or after you define the function. If you're putting it into a file that is sourced, such as ~/.bashrc, just take out the alias line and add the function definition.

Why does this work? Unlike aliases, bash shell functions can take positional parameters, i.e., command-line arguments. "$@" expands to the full argument list, causing arguments to the lso function to be passed to ls. (Unlike an alias definition, a function body is not quoted; hence it was necessary to remove the \characters before $ and ".)

Since you can pass options to lso when defined this way as a function, you may wish to remove the -a and -G options from the definition--you can pass them manually in cases where you want them. (The -l option is required for details like file permissions to be shown at all, so there is no benefit to removing it.)

lso() { ls -l "$@" | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(" %0o ",k);print}'; }

Thanks to techtonik for pointing out the limitation in defining lso as an alias, thus motivating me to expand this post with material about making it a function instead.

1One may note this seems to flaunt the general rule about not parsing output from ls. ls produces very human-readable output; this introduces idiosyncrasies and limitations making it generally unsuitable as input for other commands. In this case we parse ls since we wish to preserve the exact behavior of ls except our one added change.

share|improve this answer
doesn't work with directories - awk: read error (Is a directory) – anatoly techtonik Jul 25 '14 at 7:25
@techtonik Thanks for pointing this out! I've (finally) updated this answer to include a fix for that. – Eliah Kagan Apr 10 '15 at 20:37

Just extending\simplifying previous 'stat' related answers:

You can simply run:

stat <path_to_file>

The output will contain octal permission along with other info.

Details(stat version and example):

# stat --version
stat (GNU coreutils) 8.4

[user@localhost ~]# touch /tmp/TEST_PERMISSONS

[user@localhost ~]# chmod 644 /tmp/TEST_PERMISSONS

[user@localhost ~]# stat /tmp/TEST_PERMISSONS
  File: `/tmp/TEST_PERMISSONS'
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fd00h/64768d    Inode: 1010058     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2015-08-26 18:58:59.000000000 +0300
Modify: 2015-08-26 18:58:59.000000000 +0300
Change: 2015-08-26 18:59:16.000000000 +0300

Note the: (0644/-rw-r--r--)

share|improve this answer

For portability, you can use perl:

$ perl -e 'printf "%04o %s\n", (stat)[2] & 07777, $_ for @ARGV' *.txt
0644 1.txt
0644 2.txt
0644 3.txt
0644 4.txt
0600 PerlOneLiner.txt
0664 perl.txt

If you want to notice when an error occurs, try:

perl -e '
for (@ARGV) {
    print "$!: $_\n" and next unless -e;
    printf "%03o %s\n", (stat)[2] & 07777, $_;
' *.txt
share|improve this answer
In addition to being portable, @cuonglm's solution shows four octal characters rather than three, thus showing the state of the "sticky bit" that is often forgotten about. – Shrek Jul 22 '15 at 14:28

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.