I need to set the umask value for one specific folder. I have a web application and when it creates some file the default permission is 700. But I need at least 755 permission for that file. How can one do that?


6 Answers 6


you could use setfacl

setfacl -d -m group:name:rwx /path/to/your/dir

Where name is the group name

To find which groups you or a specific user belong see In unix/linux how do you find out what group a given user is in via command line?

  • 1
    Perhaps setfacl has changed. I am getting an error stating that -m is not a valid option. Commented Jan 10, 2015 at 19:51
  • Ryan, setfacl is not changed. Most likely you have't provided proper group name (after -m).
    – sergk
    Commented Feb 4, 2015 at 3:10
  • 4
    pretty sure setfacl is for access control lists and not umask. A better solution but not actually what was asked, I don't think.
    – Wyatt Ward
    Commented Feb 11, 2016 at 0:05
  • 1
    try: sudo setfacl -Rdm ... (Omit the R for recursion) should work. @Wyatt8740 (correct). To be certain run: man setfacl, and type /-modify. You need to use sudo.
    – JREAM
    Commented Feb 27, 2019 at 19:17

You cannot set umask per directory, it's a process-level value. If you need to prevent others from reading files in a directory, revoke the corresponding permissions bits.

For example, if you've a directory /home/user/directory with some files and directories which can get permissions like 777 from a process, set the permission bits of /home/user/directory to something like 700. That will make it impossible for other users (excluding the superuser root) to descend in /home/user/directory.

I'm paranoid and set the permissions on /home/user to 750, so only I can read, write and descend in my home directory. This has as consequence that folders like /home/user/Public cannot be accessed by others, but I can live with that.

Per update of your question: still, you cannot control that in the filesystem (other than using a different filesystem type like FAT which is strongly discougared), you need to do that in your webapp. If your webapp is coded in PHP, you can change the umask on the fly using the umask function:

// other code

You could put this in a configuration file, like the file containing the database connection password (thinking in apps like Wordpress).

Remember that it's a process value, some webservers allow you to set it in their configuration files, otherwise you could modify the startup scripts to set the desired umask. Remember that permissions like 755 and 644 are quite dangerous for webapps, if the code is sensitive, everyone can read it.

  • 2
    I know this is ancient, but I figure it's worth mentioning: the administrator can bind mount /home/user/Public (mount -o bind /home/user/Public /some/other/place) to work around the parent directory permissions issue. Commented May 8, 2018 at 15:52

Provide anther solution implemented with shell hooks and direnv. The following solution may be more compatible in case setfacl is not available on your system. (e.g. macOS)

direnv is an environment switcher for the shell. It knows how to hook into bash, zsh, tcsh, fish shell and elvish to load or unload environment variables depending on the current directory.

Use .envrc to export custom umask value for specific dir, and the exported env var will be unloaded when you leave that dir.

# example .envrc file
export UMASK=0022

Define a hook to change the umask value once working dir is changed.

function _umask_hook {
  if [[ -n $UMASK ]]; then
    umask "$UMASK"
  elif [[ $OSTYPE == darwin* ]]; then
    umask 0077
    umask 0022

# To make the code more reliable on detecting the default umask
function _umask_hook {
  # Record the default umask value on the 1st run
  [[ -z $DEFAULT_UMASK ]] && export DEFAULT_UMASK="$(builtin umask)"

  if [[ -n $UMASK ]]; then
    umask "$UMASK"
    umask "$DEFAULT_UMASK"

# zsh hooks
# trigger _umask_hook once working dir is changed
add-zsh-hook chpwd _umask_hook

# bash
# Append `;` if PROMPT_COMMAND is not empty

For the time being, direnv hook initialization for zsh doesn't support chpwd hook. If the pull request GH-514 has not been merged when you see this page. Please comment out eval "$(direnv hook zsh)" and hook direnv on chpwd manually with following code,

if (( $+commands[direnv] )) && ! (( $+functions[_direnv_hook] )); then
  _direnv_hook() {
    eval "$(command "direnv" export zsh)";
  typeset -agU precmd_functions;
  if [[ -z ${precmd_functions[(r)_direnv_hook]} ]]; then
    precmd_functions=( _direnv_hook ${precmd_functions[@]} )

  typeset -agU chpwd_functions;
  if [[ -z ${chpwd_functions[(r)_direnv_hook]} ]]; then
    chpwd_functions=( _direnv_hook ${chpwd_functions[@]} )

Source: dynamic-umask-based-on-cwd.md


Another solution might be to just set the group id on files created in the directory, which makes the new files owned by the directory group id, instead of the group id of the user that created the files. So I think you could just do:

chown www-data:www-data /my/folder
chmod 2755 /my/folder

This sets the setgid special file permission, which would cause all files created in /my/folder to be owned by the www-data group, which has then has rx (5) permission because of the parent directory.

The special permission is defined in the first digit using octal notation. Add together the numbers below to combine options (e.g. 3 for both sgid and sticky bit)

  • 1 for the sticky bit
  • 2 for sgid
  • 4 for suid

Reference: https://en.wikipedia.org/wiki/Setuid


To change permissions for a folder use chmod. umask is for files.

Set umask to what you need by

umask xxx

and change back when your done

umask 022
  • 15
    umask = files and directories, fmask = only files, dmask = only directories. :P
    – htorque
    Commented May 22, 2011 at 20:15
  • 1
    I learned something new today :)
    – wojox
    Commented May 22, 2011 at 20:23
  • 2
    Actually that are options for certain file systems like NTFS (not that file creation mask setting command umask). Sorry for adding confusing information.
    – htorque
    Commented May 22, 2011 at 20:54
  • 1
    umask changes the file-creation mask for the current process (the current shell), if you have a different shell open or user-owned process, I don't believe it will be affected. This command will also affect any other files created outside of the directory until you change it back.
    – Dave
    Commented May 3, 2017 at 14:57

Related, but maybe not applicable in this case, the following clip is from .zshrc:

# Change the umask automatically for some directories; use 0022 as the default
chpwd () {
    case $PWD in
            if [[ $(umask) -ne 077 ]]; then
                umask 0077
                echo -e "\033[01;32mumask: private \033[m"
            if [[ $(umask) -ne 072 ]]; then
                umask 0072
                echo -e "\033[01;33mumask: other readable \033[m"
            if [[ $(umask) -ne 002 ]]; then
                umask 0002
                echo -e "\033[01;35mumask: group writable \033[m"
            if [[ $(umask) -ne 022 ]]; then
                umask 0022
                echo -e "\033[01;31mumask: world readable \033[m"

So for interactive use, something like that would work (but, obviously, not to provide security).

You must log in to answer this question.

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