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

Greetings Wise Ones,
I've been messing around with this for several hours and it's driving me batty.

I want to get the permissions of files and directories on a linux system and store them in a scalar in binary. e.g. "0755"

I found this:
#!/usr/bin/perl -w $file="/tmp/test.file"; $mode = (stat($file))[2]; printf "Permissions are %04o\n", $mode & 07777;
This gives me the values I'm looking for:
Permissions are 0744
but I don't understand the "printf" function. I've read the perldoc, but I just don't get it. Also, I don't *think* I want it for the script on which I'm working.

I thought briefly about writing the values out to a file, then sucking them back in....but that just seems wrong.
I just want to store those 4 numbers in a scalar.
Can anyone help me?
Thanks!!!

Replies are listed 'Best First'.
Re: stat and permissions
by toolic (Bishop) on Jan 14, 2011 at 23:45 UTC
    I just want to store those 4 numbers in a scalar.
    Use sprintf:
    $mode = sprintf '%04o', (stat $file)[2] & 07777; print "Permissions are $mode\n";
      THANK YOU!
Re: stat and permissions
by eff_i_g (Curate) on Jan 14, 2011 at 23:41 UTC
    Did you read the perldoc for sprintf? It has more information. They're identical except sprintf "prints" to a string (what you want) and printf goes to your output.
Re: stat and permissions
by jwkrahn (Abbot) on Jan 15, 2011 at 06:20 UTC
    and store them in a scalar in binary. e.g. "0755"

    First, in a binary computer, all data is stored "in binary".    So what specifically do you mean by "binary" in this instance?

    Second, the number 0744 is the octal representation of the number 484:

    $ perl -le'print 0744' 484

    Perhaps you should read the perlnumber man page to see how Perl deals with numbers, and come back here with any follow-up questions.

Re: stat and permissions
by cdarke (Prior) on Jan 15, 2011 at 15:35 UTC
    store them in a scalar in binary. e.g. "0755"
    I just want to store those 4 numbers in a scalar.

    sprintf returns a string, and the "4 numbers" includes a leading zero which is just decoration indicating that the number is octal (base 8). Converting that string into a numeric will only remove the leading zero. If you want the value as an integer (which I assume is what you mean by 'binary') then ignore the printf or sprintf:
    use warnings; use strict; use Devel::Peek; my $file = $0; my $mode = sprintf '%04o', (stat $file)[2] & 07777; print "sprintf Permissions are $mode\n"; print "\twhich is ",oct($mode)," in decimal\n"; print Dump(\$mode),"\n\n"; my $n_mode = (stat $file)[2] & 07777; print "stat Permissions are $n_mode decimal\n"; print Dump(\$n_mode),"\n";
    In the output the string scalar $mode is "0666" but the integer scalar "$n_mode is 438:
    sprintf Permissions are 0666 which is 438 in decimal SV = RV(0x3a1b8) at 0x3a1ac REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x18abfd4 SV = PV(0x3807c) at 0x18abfd4 REFCNT = 2 FLAGS = (PADMY,POK,pPOK) PV = 0x18b1614 "0666"\0 CUR = 4 LEN = 8 stat Permissions are 438 decimal SV = RV(0x3a1b8) at 0x3a1ac REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x18bada4 SV = PVIV(0x18a0f4c) at 0x18bada4 REFCNT = 2 FLAGS = (PADMY,IOK,POK,pIOK,pPOK) IV = 438 PV = 0x18a1f2c "438"\0 CUR = 3 LEN = 4
    You can see that $mode does not have an integer value (IV) at that point, only a string value (PV).