There's no convenient way. That's why GNU find added -readable and friends.
You can build an expression that approximates the permission test by enumerating the groups that the user is in. Untested.
can_access="( -user $(id -u) -perm -0${oct}00 -o ("
for g in $(id -G); do
can_access="$can_access -group $g -o"
done
can_access="${can_access% -o} ) -perm -00${oct}0 -o -perm -000${oct} )"
find … $can_access -print
This doesn't give the correct result in some cases, for example if there are access control lists, or in edge cases such as -rw----r-- to deny access to a group. You can check for the edge cases with the same technique as above, but the expression gets even more complex. For access control lists, you need to invoke a tool that supports them.
Languages such as Perl and Python provide easy access both to the access(2) function and to the functionality of find. In Perl, with File::Find and -r/-w/-x (which use the effective uid and gid of the Perl process — use -R/-W/-X to check with the real uid/gid like access(2), and use the filetest 'access' pragma if your Perl isn't too ancient to have it to support things like ACL):
use File::Find;
use filetest 'access';
find(sub { if (-r $_) { print "$_ is readable\n"; } }, '.');
In Python, with os.walk and os.access (which uses the real uid and gid of the Python process, like access(2)):
import os
for dirpath, dirnames, filenames in os.walk('.', ):
for filename in filenames:
filename = os.path.join(dirpath, filenames)
if os.access(filename, os.R_OK):
print(filename + ' is readable\n')
The only fully reliable way is to try to open the file. This requires an external utility, so it'll be slower. To test for readability of a regular file:
find … -exec sh -c 'exec 2>/dev/null; : <"$0"' {} \; …
To test for writability, use : >>"$0" (this opens the file for appending, so it'll fail if the file isn't writable, but it doesn't actually modify anything, and in particular won't update the modification time). To test a directory for readability, use ls -- "$0" >/dev/null. To test a directory for executability, use cd -- "$0".
There's no passive test for executability of a regular file, for writability of a directory, or for access to most non-regular files.