in reply to What does ">>" do? (And other stat questions)

As for the sprintf line, this session under the debugger shows you how the $mode value (coming from stat($file)[2]) might be converted:

DB<1> @c = stat "data.txt"; DB<2> x @c 0 1946693715 1 6473924464489865 2 33261 3 1 4 1001 5 513 6 0 7 64 8 1375303088 9 1375303088 10 1375303088 11 65536 12 1 DB<3> $mode = $c[2]; DB<4> printf "%04o", $mode ; 100755 DB<5> printf "%04o", $mode & 07777; 0755

BTW, my "data.txt" does indeed have the 0755 permissions:

$ ls -l data.txt -rwxr-xr-x 1 Laurent None 64 31 juil. 22:38 data.txt

In the Unix file permission system, "rwxr-xr-x" is the same as the 0755 octal value.

Replies are listed 'Best First'.
Re^2: What does ">>" do? (And other stat questions)
by three18ti (Monk) on Nov 01, 2013 at 00:39 UTC

    Hello,

    Thanks for taking the time to debug and respond.

    Could you please give me a little insight to what this means:

    DB<4> printf "%04o", $mode ; 100755 DB<5> printf "%04o", $mode & 07777; 0755

    I think you're trying to show me what happens when you binary "&" 33261 and 07777? maybe that doesn't make any sense because the 07777 isn't present in DB<4> but is in DB<5>. I read in a link above that "&" has lower precedence, so that would bean that "printf "%04o", $mode" is evaluated first? But that doesn't make any sense since printf would do the printing... Ok, I thought I was starting to understand... But I don't think I do.

      The $mode value is 33261. I wanted to show what happens when you print it with the octal formatting string (prints 100755) and when you do it after having modified it with the binary and (&). And & has a higher precedence than the comma. As you can see below, adding parens to guarantee the right precedence does not modify the output::

      DB<1> $mode = 33261; DB<2> printf "%04o", $mode; 100755 DB<3> printf "%04o", $mode & 07777; 0755 DB<4> printf "%04o", ($mode & 07777); 0755 DB<5>

      From your other answers, I think I can help you further by showing the same numbers as above in binary form:

      DB<5> printf "%04b", $mode ; 1000000111101101 DB<6> printf "%04b", 07777; 111111111111 DB<7>

      So, 33261 is 1000000111101101 in binary representation, and 07777 is 111111111111 (or the equivalent 0000111111111111) in binary representation. If we now do manually a bitwise and (&) between these two numbers, we do this:

      1000000111101101 & 0000111111111111 ================ = 0000000111101101

      We get a 1 in the result only at places where we have a 1 in both numbers above. This is in effect applying a mask to cancel out the four binary digits on the left in the original number. The same operation under the debugger:

      DB<8> $c = $mode & 07777; DB<9> printf "%04b", $c; 111101101 DB<10>

      If I now print that same $c number in its octal representation:

      DB<10> printf "%04o", $c; 0755 DB<11>

      Is it clearer in your mind now?

        Awesome! Thanks so much for the explanation.

        I think I understand everything except for why we're essentially throwing away the first four bits. Why are they there to begin with? And why don't we need them?

        Thanks again, this is awesome