Why is a file with 400 permissions seen writable by root but read-only by user?
I think you have have misunderstood what
-w does. It does not check to see if the file has "Write permissions", it checks to see if the file is writable by the invoking user.
More specifically, it calls
access(2) or similar.
eg if a script has
if [ -w /etc/shadow ] then if you run
strace on the script you may see a line similar to
faccessat(AT_FDCWD, "/etc/shadow", W_OK)
root can write to the file then it returns 0.
eg as a normal user:
faccessat(AT_FDCWD, "/etc/shadow", W_OK) = -1 EACCES (Permission denied)
faccessat(AT_FDCWD, "/etc/shadow", W_OK) = 0
This, despite the fact that
/etc/shadow has permission
000 on my machine.
---------- 1 root root 4599 Jan 29 20:08 /etc/shadow
Now what you want to do gets interesting and isn't so simple.
If you want to check the simple permissions then check the
ls output, or call
stat or similar. But realize that ACLs can over-ride these permissions. Just because a file is permission 400 doesn't stop it from being writable...
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
%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
(( ... )).