Why is a file with 400 permissions seen writable by root but read-only by user

permissionsreadonlytest

If I create a file as an unprivileged user, and change the permissions mode to 400, it's seen by that user as read-only, correctly:

$ touch somefile
$ chmod 400 somefile
$ [ -w somefile ] && echo rw || echo ro
ro

All is well.

But then root comes along:

# [ -w somefile ] && echo rw || echo ro
rw

What the heck? Sure, root can write to read-only files, but it shouldn't make a habit of it: Best Practice would tend to dictate that I should be able to test for the write permission bit, and if it's not, then it was set that way for a reason.

I guess I want to understand both why this is happening, and how can I get a false return code when testing a file that doesn't have the write bit set?

Best Answer

test -w aka [ -w doesn't check the file mode. It checks if it's writable. For root, it is.

$ help test | grep '\-w'
  -w FILE        True if the file is writable by you.

The way I would test would be to do a bitwise comparison against the output of stat(1) ("%a Access rights in octal").

(( 0$(stat -c %a somefile) & 0200 )) && echo rw || echo ro

Note the subshell $(...) needs a 0 prefixed so that the output of stat is interpreted as octal by (( ... )).

Related Question