Can the Unix list command 'ls' output numerical chmod permissions?

UnixCommand LinePermissions

Unix Problem Overview


Is it possible when listing a directory to view numerical unix permissions such as 644 rather than the symbolic output -rw-rw-r--

Thanks.

Unix Solutions


Solution 1 - Unix

it almost can ..

 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}'

Solution 2 - Unix

Closest I can think of (keeping it simple enough) is stat, assuming you know which files you're looking for. If you don't, * can find most of them:

/usr/bin$ stat -c '%a %n' *
755 [
755 a2p
755 a2ps
755 aclocal
...

It handles sticky, suid and company out of the box:

$ stat -c '%a %n' /tmp /usr/bin/sudo
1777 /tmp
4755 /usr/bin/sudo

Solution 3 - Unix

you can just use GNU find.

find . -printf "%m:%f\n"

Solution 4 - Unix

You can use the following command

stat -c "%a %n" *

Also you can use any filename or directoryname instead of * to get a specific result.

On Mac, you can use

stat -f '%A %N' *

Solution 5 - Unix

Use this to display the Unix numerical permission values (octal values) and file name.

stat -c '%a %n' *

Use this to display the Unix numerical permission values (octal values) and the folder's sgid and sticky bit, user name of the owner, group name, total size in bytes and file name.

stat -c '%a %A %U %G %s %n' *

enter image description here

Add %y if you need time of last modification in human-readable format. For more options see stat.

Better version using an Alias

Using an alias is a more efficient way to accomplish what you need and it also includes color. The following displays your results organized by group directories first, display in color, print sizes in human readable format (e.g., 1K 234M 2G) edit your ~/.bashrc and add an alias for your account or globally by editing /etc/profile.d/custom.sh

Typing cls displays your new LS command results.

alias cls="ls -lha --color=always -F --group-directories-first |awk '{k=0;s=0;for(i=0;i<=8;i++){;k+=((substr(\$1,i+2,1)~/[rwxst]/)*2^(8-i));};j=4;for(i=4;i<=10;i+=3){;s+=((substr(\$1,i,1)~/[stST]/)*j);j/=2;};if(k){;printf(\"%0o%0o \",s,k);};print;}'"

Alias is the most efficient solution

Folder Tree

While you are editing your bashrc or custom.sh include the following alias to see a graphical representation where typing lstree will display your current folder tree structure

alias lstree="ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/'"

It would display:

   |-scripts
   |--mod_cache_disk
   |--mod_cache_d
   |---logs
   |-run_win
   |-scripts.tar.gz

Solution 6 - Unix

@The MYYN

wow, nice awk! But what about suid, sgid and sticky bit?

You have to extend your filter with s and t, otherwise they will not count and you get the wrong result. To calculate the octal number for this special flags, the procedure is the same but the index is at 4 7 and 10. the possible flags for files with execute bit set are ---s--s--t amd for files with no execute bit set are ---S--S--T

ls -l | awk '{
    k = 0
    s = 0
    for( i = 0; i <= 8; i++ )
    {
        k += ( ( substr( $1, i+2, 1 ) ~ /[rwxst]/ ) * 2 ^( 8 - i ) )
    }
    j = 4 
    for( i = 4; i <= 10; i += 3 )
    {
        s += ( ( substr( $1, i, 1 ) ~ /[stST]/ ) * j )
        j/=2
    }
    if ( k )
    {
        printf( "%0o%0o ", s, k )
    }
    print
}'  

For test:

touch blah
chmod 7444 blah

will result in:

7444 -r-Sr-Sr-T 1 cheko cheko   0 2009-12-05 01:03 blah

and

touch blah
chmod 7555 blah

will give:

7555 -r-sr-sr-t 1 cheko cheko   0 2009-12-05 01:03 blah

Solution 7 - Unix

You don't use ls to get a file's permission information. You use the stat command. It will give you the numerical values you want. The "Unix Way" says that you should invent your own script using ls (or 'echo *') and stat and whatever else you like to give the information in the format you desire.

Solution 8 - Unix

Building off of the chosen answer and the suggestion to use an alias, I converted it to a function so that passing a directory to list is possible.

# ls, with chmod-like permissions and more.
# @param $1 The directory to ls
function lls {
  LLS_PATH=$1

  ls -AHl $LLS_PATH | 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}"
}

Solution 9 - Unix

Considering the question specifies UNIX, not Linux, use of a stat binary is not necessary. The solution below works on a very old UNIX, though a shell other than sh (i.e. bash) was necessary. It is a derivation of glenn jackman's perl stat solution. It seems like an alternative worth exploring for conciseness.

$ alias lls='llsfn () { while test $# -gt 0; do perl -s -e \
  '\''@fields = stat "$f"; printf "%04o\t", $fields[2] & 07777'\'' \
    -- -f=$1; ls -ld $1; shift; done; unset -f llsf; }; llsfn'
$ lls /tmp /etc/resolv.conf
1777    drwxrwxrwt   7 sys      sys       246272 Nov  5 15:10 /tmp
0644    -rw-r--r--   1 bin      bin           74 Sep 20 23:48 /etc/resolv.conf

The alias was developed using information in this answer

The whole answer is a modified version of a solution in this answer

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJon WinstanleyView Question on Stackoverflow
Solution 1 - UnixmikuView Answer on Stackoverflow
Solution 2 - UnixJB.View Answer on Stackoverflow
Solution 3 - Unixghostdog74View Answer on Stackoverflow
Solution 4 - UnixMohd Abdul MujibView Answer on Stackoverflow
Solution 5 - UnixErick GonzalezView Answer on Stackoverflow
Solution 6 - Unixuser224243View Answer on Stackoverflow
Solution 7 - UnixEvan LangloisView Answer on Stackoverflow
Solution 8 - UnixCurtis BlackwellView Answer on Stackoverflow
Solution 9 - UnixkbulgrienView Answer on Stackoverflow