I have an umask as a 0002 using umask -S it returns u=rwx,g=rwx,o=rx.

How do I find all files and directories that does not have rights set up according to mask?

The directories goes 777 - mask and files 666 - mask If i do something like

find . ! -perm $(umask -S) 

it will find all files/directories that does not have rights set to u=rwx,g=rwx,o=rx ( 777 - 002 are there rights but 666 - 002 are different rights) which is good for directories, but not for files.

How do I find files, that have different rights than current set umask ?


 touch one
 ls -l
 -rw-rw-r-- 1 trolkura trolkura 0 kvě  4 09:01 one

umask is 0002 so this results in 664 , but when I do

find . -type f ! -perm $(umask -S)

result shows newly created file because it is looking for files that does not have 775 rights (Directory rights).

  • According to your question, you wanna search all files which doesn't have 0662 permission right ?
    – Rahul
    May 4, 2016 at 7:16
  • 0664 but yes i do
    – trolkura
    May 4, 2016 at 7:22

2 Answers 2


Why don't you try this one :

find . -user trolkura ! -perm -u+rw

This means: look for files starting in present directory, owned by trolkura, where the permissions for group and other can be anything (- in front of permission string) and the users permissions are only: rw


You can use the octal forms and do the calculations by hand. With a POSIX shell:

dir_perms=$(printf '%#o' "$((0777 - $(umask)))")
non_dir_perms=$(printf '%#o' "$((dir_perms & 0666))")
find . -type d ! -perms "$dir_perms" -o ! -type d ! -perms "$non_dir_perms"

The output format of umask alone is not specified by POSIX but in practice, will all shells, it's an octal number with at least one leading 0.

zsh doesn't treat numbers with leading 0s as octal by default. In zsh, you can either enable sh emulation in a local context for that ((){ emulate -L sh; ....} or (emulate sh; ...) or just set -o octalzeroes) or use:

dir_perms=0$(([##8] 8#777 - 8#$(umask)))
non_dir_perms=0$(([##8] 8#$dir_perms & 8#666))

With mksh that doesn't treat numbers with leading 0s as octal by default either, you can use set -o posix or do:

dir_perms=$(printf '%#o' "$((8#777 - 8#$(umask)))")
non_dir_perms=$(printf '%#o' "$((8#$dir_perms & 8#666))")
  • Could you please explain the code for the OP? May 4, 2016 at 8:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .