Skip to content
shellhacks.dev
Shell Scripting

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.

1 min read
Summarize in AI

A script should use a file only when it exists, can be read and has some content.

Shell
: > 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"
Text
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.

Share

More snippets

Shell Scripting

Compare Dotted Version Numbers in POSIX sh

Compare dotted version numbers in POSIX sh by splitting on dots and comparing each field as an integer. Plain sort puts 1.10 before 1.9, and sort -V is a GNU option.

1 min read
Shell Scripting

Return Text from a Function in POSIX sh

A POSIX sh function returns text by printing it, and the caller captures the output with command substitution. Variables set inside are lost, and trailing newlines go.

1 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.