Tux

...making Linux just a little more fun!

2-cent Tip: Octal permissions in "ls"

Ben Okopnik [ben at linuxgazette.net]


Sat, 26 Mar 2011 22:53:50 -0400

I've always wondered why "ls" doesn't just have this as an option. Got tired of wondering, so I went ahead and wrote it.

This script is intended to be a drop-in replacement for "ls" - in other words, just put it somewhere accessible and alias it to 'ls'. It takes all the same options that 'ls' does (no wonder; it simply passes the entire argument string to 'ls'), and works in the same way, unless the first option that you specify - and it must be specified by itself - is "-O" (capital "o", not a zero.) In that case, it does all the same stuff but reformats the output a little - just the filetype/permissions section. I haven't done a huge amount of testing on it, so it might be fragile in some unexpected places (reports would be appreciated). Seems OK, though, so I'm releasing it to the unsuspecting world. Enjoy.

#!/usr/bin/perl -w
# Created by Ben Okopnik on Sat Mar 26 19:00:46 EDT 2011
use strict;
 
if ($ARGV[0] ne '-O'){ exec '/bin/ls', @ARGV } else { shift; }
 
for (qx#/bin/ls @ARGV#){
    my ($t, $p, $r) = /^(.)([rwxsStT-]+)(\s+\d+\s+\w+.+)$/;
    print and next unless $p;
 
    my $out = 0;
    my %d = map {split//} qw/sx S- r4 w2 x1 -0/;
    $out += 01000 if $p =~ y/tT/x-/;
    $out += 02000 if $p =~ s/(s)(?=.{3})$/$d{$1}/i;
    $out += 04000 if $p =~ s/(s)(?=.{6})$/$d{$1}/i;
 
    $p =~ s/([rwx-])// and $out += $d{$1} * oct($_) for (100)x3, (10)x3, (1)x3;
 
    printf "[%s] %04o  %s\n", $t, $out, $r;
}
-- 
* Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *


Top    Back


Ben Okopnik [ben at linuxgazette.net]


Sat, 26 Mar 2011 23:01:01 -0400

On Sat, Mar 26, 2011 at 10:53:50PM -0400, Benjamin Okopnik wrote:

> I've always wondered why "ls" doesn't just have this as an option. Got
> tired of wondering, so I went ahead and wrote it.

And _of course_ the second I send it off, I realize that I've sent the "2 versions back" version instead of the one I've been using. [sigh] Let's try this again.

#!/usr/bin/perl -w
# Created by Ben Okopnik on Sat Mar 26 19:00:46 EDT 2011
use strict;
 
if (@ARGV&&$ARGV[0] ne '-O'){ exec '/bin/ls', @ARGV } else { shift; }
 
for (qx#/bin/ls @ARGV#){
    my ($t, $p, $r) = /^(.)([rwxsStT-]+)(\s+\d+\s+\w+.+)$/;
    print and next unless $p;
 
    my $out = 0;
    my %d = map {split//} qw/sx S- r4 w2 x1 -0/;
    $out += 01000 if $p =~ y/tT/x-/;
    $out += 02000 if $p =~ s/(s)(?=.{3})$/$d{$1}/i;
    $out += 04000 if $p =~ s/(s)(?=.{6})$/$d{$1}/i;
 
    $p =~ s/([rwx-])// and $out += $d{$1} * oct($_) for (100)x3, (10)x3, (1)x3;
 
    printf "[%s] %04o  %s\n", $t, $out, $r;
}
-- 
* Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *


Top    Back


Ben Okopnik [ben at linuxgazette.net]


Sat, 26 Mar 2011 23:43:13 -0400

Hi, Santosh -

On Sun, Mar 27, 2011 at 09:02:29AM +0530, Sivaraj S wrote:

> >
> Hi Ben,
> 
> I am not sure whether I am doing this right, but the output doesn't show/print
> the octal values of the permissions. if the ls version matters, it's version 8.5.
> 
> I suppose the first column in the permission should be in octal, right?

Your version of "ls" does something I've never seen before: there's a '.' at the end of your permissions (and that's why it's not working for you.) I could easily tweak that in the script, but - what is that? What does it mean?

> git $ octalls.pl -O -l
> total 20
> drwxr-xr-x.  6 santosh santosh 4096 Mar 14 08:59 bti
> drwxr-xr-x.  5 santosh santosh 4096 Mar 15 22:46 gitolite-admin
> drwxr-xr-x. 24 santosh santosh 4096 Mar 12 02:00 kernel-omap
> drwxr-xr-x. 24 santosh santosh 4096 Mar 27 08:48 linux-2.6
> drwxrwxr-x.  4 santosh santosh 4096 Jul 18  2010 tlock
-- 
* Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *


Top    Back


Ben Okopnik [ben at linuxgazette.net]


Sun, 27 Mar 2011 08:42:11 -0400

On Sat, Mar 26, 2011 at 11:52:35PM -0700, Joey Prestia wrote:

> 
> "GNU ls uses a ‘.’ character to indicate a file with an SELinux security
> context, but no other alternate access method. "

Perfect; that's what I wanted to know. The fix is trivial - I just look for an optional dot following the perm string (it'll even be replicated in the result - that's why I wanted to know what it meant).

#!/usr/bin/perl -w
# Created by Ben Okopnik on Sat Mar 26 19:00:46 EDT 2011
use strict;
 
if (@ARGV&&$ARGV[0] ne '-O'){ exec '/bin/ls', @ARGV } else { shift; }
 
for (qx#/bin/ls @ARGV#){
    my ($t, $p, $r) = /^(.)([rwxsStT-]+)(\.?\s+\d+\s+\w+.+)$/;
    print and next unless $p;
 
    my $out = 0;
    my %d = map {split//} qw/sx S- r4 w2 x1 -0/;
    $out += 01000 if $p =~ y/tT/x-/;
    $out += 02000 if $p =~ s/(s)(?=.{3})$/$d{$1}/i;
    $out += 04000 if $p =~ s/(s)(?=.{6})$/$d{$1}/i;
 
    $p =~ s/([rwx-])// and $out += $d{$1} * oct($_) for (100)x3, (10)x3, (1)x3;
 
    printf "[%s] %04o  %s\n", $t, $out, $r;
}
-- 
* Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *


Top    Back


Ben Okopnik [ben at linuxgazette.net]


Sun, 27 Mar 2011 08:58:32 -0400

On Sun, Mar 27, 2011 at 12:44:53PM +0100, Thomas Adam wrote:

> On 27 March 2011 03:53, Ben Okopnik <[email protected]> wrote:
> > I've always wondered why "ls" doesn't just have this as an option. Got
> > tired of wondering, so I went ahead and wrote it.
> 
> Nice -- there's several tools like this now about -- to
> enhance/transform the output of commands and add colour to them.  When
> I can find them, I'll let everyone know.
> 
> > This script is intended to be a drop-in replacement for "ls" - in other
> > words, just put it somewhere accessible and alias it to 'ls'. It takes
> 
> Ben... all that perl.   :)  Why, I've been using the following for ages:
> 
> ```
> stat --printf=%a\\t%U\\t%G\\t%t\\t%n\\n /some/where
> '''
> 
> Which is cheating, and nothing like "ls", but... :)

I had almost the same thing myself, also for years:

ls-l () { stat -c "%04a  %2h %-5.5U %-5.5G%6s %16.16x %n" "$@"|sort -k8; }

but the sorting order sucked (and no way to fix it simply), it was hard to get it to do the right thing with regard to, say, dotfiles (it always acted similar to "ls -d"), and the formatting around %U and %G always did weird things. I wanted the same exact familiar interface I'd been using for years, with the same layout but one small change. That is the cool thing here - not just the permissions themselves. Although that's a fairly clever parser for them if I do say so myself. :)

-- 
* Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *


Top    Back


Ben Okopnik [ben at okopnik.com]


Sun, 27 Mar 2011 11:32:28 -0400

On Sun, Mar 27, 2011 at 08:05:51AM -0700, Joey Prestia wrote:

> 
> Can we enhance it to make it catch the files with ACL's on them
> signified by a plus + sign?
> 
> [d] 0755  .  2 joey joey  4096 Sep  7  2010 Music
> - -rw-rwxr--+  1 joey joey    37 Mar 26 23:39 new
> [d] 0755  .  2 joey joey  4096 Sep  7  2010 Pictures
> [d] 0755  .  2 joey joey  4096 Sep  7  2010 Public
> 
> Almost forgot about those.

I never even knew about that notation in the first place. :) Sure, easy enough:

#!/usr/bin/perl -w
# Created by Ben Okopnik on Sat Mar 26 19:00:46 EDT 2011
use strict;
 
if (@ARGV&&$ARGV[0] ne '-O'){ exec '/bin/ls', @ARGV } else { shift; }
 
for (qx#/bin/ls @ARGV#){
    my ($t, $p, $r) = /^(.)([rwxsStT-]+)([.+]?\s+\d+\s+\w+.+)$/;
    print and next unless $p;
 
    my $out = 0;
    my %d = map {split//} qw/sx S- r4 w2 x1 -0/;
    $out += 01000 if $p =~ y/tT/x-/;
    $out += 02000 if $p =~ s/(s)(?=.{3})$/$d{$1}/i;
    $out += 04000 if $p =~ s/(s)(?=.{6})$/$d{$1}/i;
 
    $p =~ s/([rwx-])// and $out += $d{$1} * oct($_) for (100)x3, (10)x3, (1)x3;
 
    printf "[%s] %04o  %s\n", $t, $out, $r;
}

Ben

-- 
                       OKOPNIK CONSULTING
        Custom Computing Solutions For Your Business
Expert-led Training | Dynamic, vital websites | Custom programming
  443-250-7895   http://okopnik.com   http://twitter.com/okopnik


Top    Back


Ben Okopnik [ben at linuxgazette.net]


Sun, 27 Mar 2011 20:14:10 -0400

On Mon, Mar 28, 2011 at 01:37:21AM +0700, Mulyadi Santosa wrote:

> 
> regex regex and regex.... Ben do his magic perl whiz again.... :)

Regexen, as I never tire of reminding my students, are a language of their own and useful in many different contexts. Perl, among other languages and systems, uses it, but that doesn't make it unique. Although it does have some features integrated into its regex engine that would be useful if implemented in other places (e.g., it would be nice if Python supported PCREs.)

> OK, this is really interesting..and I wonder, could it be made into
> official mainline coreutils package somehow? that would be helping so
> many Linux newbies IMHO

Oh, it would have been much simpler for a C programmer (or whatever 'ls' is written in) to add it in the 'ls' code in the first place; after all, the whole 'rwx' syntax had to be computed from the stat call, not the other way around. However, the author(s) of 'ls' got allergic to the number of options that it supported and refused to add any more, no matter how sensible they might have been. Heck, as I understand it, the option to show octal perms existed in the pre-GNU versions of 'ls' (that's what "-?" did.)

In the main, I just found the whole process of figuring out how to write a wrapper around an existing utility to be an interesting exercise.

-- 
* Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *


Top    Back