This question seems an easy one for anyone who knows find command. But let's assume that find command doesn't work on my system. How can I view the files based on their permissions without using "find" command?

  • 4
    any specific reason for not using find ? – Rahul Jun 6 '16 at 9:24
  • did any of us answer helped you or not ? – Rahul Jun 16 '16 at 9:09
  • Yes, It really helped me a lot. – Debasish Jun 17 '16 at 9:58
  • No, I am new to this site – Debasish Jun 18 '16 at 11:01

Without find, you still have a shell (which can expand wildcards) and can loop over the contents of the directory checking first if each is a file, then if it is not writable, and then if it is not executable and then if it is readable.

Someone is likely to write a script to demonstrate, but it helps to start by reading the documentation, e.g., POSIX test.

By the way, the use of "only" in the question's title would exclude results where the file is either writable or executable. In POSIX find, you can express it like this:

find . -type f \! \( -perm -u=w -o -perm -u=x -o -perm -g=w -o -perm -g=x -o -perm -o=w -o -perm -o=x \)

GNU find provides extensions which allow more compact expressions:

find . -type f \! -perm /u=wx,g=wx,o=wx 

The test utility (more often used as [ and ]) provides simpler tests than find, e.g.,

for name in *; do [ -f "$name" -a -r "$name" -a ! -w "$name" -a ! -x "$name" ] && ls -l "$name"; done

However, its permissions are only for the user, not group or other. To exclude files based on those, you can use ls, e.g.,

for name in *; do [ -f "$name" ] && case "$(ls -l "$name")" in -r--r--r--*) echo "$name";; esac; done

or (if you want to allow executable files)

for name in *; do [ -f "$name" ] && case "$(ls -l "$name")" in -r-?r-?r-*) echo "$name";; esac; done

You could use ls -l in conjunction with grep:

ls -l | grep -e "-r[w-][x-][r-][w-][x-][r-][w-][x-]"

This would show you only files that you have read permission to. If you add [-d] instead of the dash at the beginning of the pattern, you would get also directories.

  • 2
    grep -e "-r[rwx-]{8}" is probably a bit nicer to read – Michael Jun 6 '16 at 11:57
  • 2
    @Michael nicer to read yes, however I specifically chose the long version because it is more educational. Also, it is easier adapted to specific needs (by replacing a certain brace with the respective letter to be queried for). – Thawn Jun 6 '16 at 12:02

you can use,

# for file in /your/path/*; do [ -r "$file" ] && [ -f "$file" ] && printf '%s\n' "$file"; done
  • -r stands for, file exists and read permission is granted.

To find readable files regardless of owner, group or others, you can check the r flag in the file permission column of ls.

ls -l | awk '$1 ~ /r/'
  • Not bad, but you can simplify it and increase robustness: for f in /your/path/*; do [ -r "$f" ] && [ -f "$f ] && printf '%s\n' "$f"; done. Also see Why is printf better than echo? and Why does my shell script choke on whitespace or other special characters? – Wildcard Jun 6 '16 at 22:18
  • @Wildcard why to use [ -f $f ] ? because -r itself checks for file existence and readable – Rahul Jun 7 '16 at 5:03
  • 1
    -f checks that a file is a regular file. -r checks for readability. [ -r somedirectory ] will return true. Perhaps the Original Poster wanted to include readable directories in his results list, but when you're new to a language it's easier to remove the flags (options) you don't need than to add options you don't know, so I thought it better to assume he wanted regular files only. (Also, it's [ -f "$f" ], not [ -f $f ].) ;) – Wildcard Jun 7 '16 at 6:30
  • @Wildcard Ohh, thanks, edited my answer as per your suggestion. – Rahul Jun 7 '16 at 6:35

Along the lines of what Thawn said above, aiming for the simplest solution as a priority (and assuming you can use ls, since you can't use find;

you could do ls -l | grep ^.r\-\- to find exactly what you asked for, "files that have read permission only..."

For example

touch testfile.txt
chmod 0400 testfile.txt
ls -l | grep ^.r\-\-


`-r--------   1 youruser  yourgroup     0  6 Jun 11:20 testfile.txt'
  • Obviously it might be a lot more "fun" to an experienced user to loop over the directory with scripts like many have already written here – olaf atchmi Jun 6 '16 at 9:45

With zsh:

view ./*(.^f-444)


view ./*(.r,.A,.R)

Would view the non-hidden regular files that have at least one of the read permission bits set. Equivalent of:

find . ! -name . -prune ! -name '.*' -type f \(
  -perm -001 -o -perm -010 -o -perm -100 \)

or with GNU find:

find . -maxdepth 1 ! -name '.*' -type f -perm /444


view ./*(.e:'[ -r $REPLY ]':)

would view the non-hidden regular files that you have permission to read. Equivalent of:

find . ! -name . -prune ! -name '.*' -type f -exec test -r {} \; -print

Or with GNU find:

find . -maxdepth 1 ! -name '.*' -type f -readable


view ./*(.f-7333^f-444)

To view non-hidden regular files where only read permission bits (at least one) are set.

Equivalent of GNU find's:

find . -maxdepth 1 ! -name '.*' -perms /444 ! -perms /7333

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.