Home > Net >  How to test a file is readable as root?
How to test a file is readable as root?

Time:03-14

I wrote a shell script that reads files in /proc and /sys (for example). The script uses if [ -r "$1" ]; then to test if a file is readable before trying to read it.

Unfortunately it seems that test -r is succeeding, even if the file has no read permission (e.g. "--w-------"), but still an actual read (e.g. file - <"$1") fails with "Permission denied".

(My guess is that test assumes root can read every file)

An example for such a file would be /sys/devices/virtual/net/br0/bridge/flush in Linux.

How can I test the "readable" property properly (and efficiently) in a shell script?

More Details

# ll -d /sys/devices/virtual/net/br0/bridge /sys/devices/virtual/net/br0/bridge/flush
drwxr-xr-x 2 root root    0 Mar  1 01:37 /sys/devices/virtual/net/br0/bridge
--w------- 1 root root 4096 Mar  1 07:58 /sys/devices/virtual/net/br0/bridge/flush

CodePudding user response:

If you don't care about who can read the file (i.e. where the 'r' exists in permission bits), then you could use something like this:

if [[ `ls -l "$1" | cut -d " " -f1` =~ "r" ]]; then echo "Readable"; else echo "Unreadable"; fi

Otherwise, if you want to test a specific read bit (e.g. owner), then you could use something like this:

P=`ls -l "$1" | cut -d " " -f1`
if [[ "${P:1:1}" == 'r' ]]; then echo "Readable"; else echo "Unreadable"; fi

Alternatively, you could test the file readability as the user willing to run the command file - <"$1" as follows:

sudo -i -u someuser bash << EOF
if [ -r "$1" ]; then echo "Readable"; else echo "Unreadable"; fi
EOF
if [ -r "$1" ]; then echo "Readable"; else echo "Unreadable"; fi

Run the previous command as "root" and notice the output.

P.S. If you need to run the commands inside the script as some user, Why do you run the script as "root"?

CodePudding user response:

To read the "r" bit of the user part of the permission bits ("u r"), this command could be used, assuming it's a bit more efficient than https://stackoverflow.com/a/71460604/6607497 (using GNU sed 4.4):

stat -c %A "$1" | sed -n -e '/^.r/q0;q1'; echo $?

The command will exit with success (0) for permissions "u r", with failure (1) otherwise.

However the file could be readable even when "u r" is not true. For example a normal directory without any read permissions can be read by root.

For files only, this is probably most efficient and correct for files) in bash:

{ local dummy=$(< "$1"); } 2> /dev/null
echo $?

The command will exit with success (0) when "$1" was readable, with failure (1) otherwise. However for directories it will always exit with failure (1).

  • Related