Check a File Is Readable and Non-Empty in POSIX sh
Test that a file is readable and not empty with the POSIX tests -r and -s joined by &&. Root passes -r on a file with mode 000, as the run shows.
A script should use a file only when it exists, can be read and has some content.
: > empty
echo data > full
echo secret > locked
chmod 000 locked
t='for f in empty full locked missing; do if [ -r "$f" ] && [ -s "$f" ]; then echo "$f: usable"; else echo "$f: no"; fi; done'
echo "as root:"
sh -c "$t"
echo "as uid 1000:"
setpriv --reuid=1000 --regid=1000 --clear-groups sh -c "$t"as root:
empty: no
full: usable
locked: usable
missing: no
as uid 1000:
empty: no
full: usable
locked: no
missing: no-s is true when the file exists and has a size above zero, and -r is true when the current user can read it, so the pair covers the empty file, the missing file and the unreadable file. As root, -r is true even for a file with mode 000, because root bypasses the permission bits; the second run, dropped to uid 1000 with setpriv, reports it correctly. Both tests are in test.
The test is a check and not a guarantee, since the file can change between the test and the read, so open it directly and handle the error when that matters. Both tests follow symbolic links, so a dangling link fails them.