stefan k has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,
I'm sure that there is an elegant and perlish solution to this. I'm also pretty sure that it involves the pack or unpack function. Still: I can't get to it :(

The problem is that I want to convert a typical permissions-string (from ls -l) to it's octal representation. For simplicity we should consider the first char (usually 'd' or 'l' or '-') stripped.

rw-rw----
converts to
0660
Please enlighten me with your knowledge.

Regards... Stefan

Replies are listed 'Best First'.
Re: Converting Permissionstring to Octal
by jeroenes (Priest) on May 16, 2001 at 13:49 UTC
      Thanks.
      I should have used the magic word 'convert' in my SuperSearch ...
      Actually it is not really elegant, but it will do for me.

      One more Thank You

      Regards... Stefan

Re: Converting Permissionstring to Octal
by blue_cowdawg (Monsignor) on May 16, 2001 at 17:52 UTC

    I'm going to eschew the unpack or pack functions in my reply. Here is one way to accomplish what you are after. There are more elegant ways I'm sure.

    #!/usr/bin/perl ################################################################# $|=1; use strict; my $permstring="rw-rw----"; my $num=0; for (my $i=0;$i<9;$i+=3) { $num = ($num * 8) + getoctal(substr($permstring,$i,3)); } printf "%o\n",$num; exit(0); sub getoctal { my $str=shift; my $rval=0; $rval+=4 if substr($str,0,1) ne '-'; $rval+=2 if substr($str,1,1) ne '-'; $rval+=1 if substr($str,2,1) ne '-'; return $rval; } ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Peter L. Berghold --- Peter@Berghold.Net "Those who fail to learn from history are condemned to repeat it."
(tye)Re: Converting Permissionstring to Octal
by tye (Sage) on May 16, 2001 at 22:45 UTC

    Well, if you only ever have "r", "w", "x", and "-" present, then you can use pack/unpack for this:

    sub perm2mode { my( $perm )= @_; if( 9 != length($perm) || 9 != ( $perm =~ tr/rwx-/1110/ ) ) { die "Unsupported permission string ($_[0])"; } return unpack "v", pack "b*", ''.reverse$perm; }
    Use sprintf "0%o" on the return value if you want an octal string, but don't try to use that octal string as a number or you'll get the wrong number:
    my $mode= perm2mode("rw-r----x"); my $str= sprintf "0%o", $mode; print "mode=$mode str=$str\n"; my $bad= 0+$str; printf "bad=%d=0%o mode=%d=0%o\n", $bad, $bad, $mode, $mode;
    produces:
    mode=417 str=0641 bad=641=01201 mode=417=0641
    So, for example, using chmod $str, $file; would be wrong just like chmod "0660", $file; is.

            - tye (but my friends call me "Tye")