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 '16 at 7:16
  • 0664 but yes i do – trolkura May 4 '16 at 7:22

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

| improve this answer | |

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))")
| improve this answer | |
  • Could you please explain the code for the OP? – MatthewRock May 4 '16 at 8:38

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.