You create a text file in a terminal and get 644.
A script creates another file with 600. Both belong
to the same account. Linux umask helps explain the difference:
each creating process carries a mask that can remove permission
bits from the mode it requests.
This lesson explains where those initial permissions come from, how to read common masks, and how to test them without changing your login settings or existing files. Familiarity with owner, group and other permission bits will help.
- How Linux umask sets initial permissions
- Reading 022, 027 and 077
- Use a bitwise filter, not subtraction
- Try two masks without changing your login shell
- Why a service can differ from your terminal
- When the mask does not explain the whole result
- The parent directory has a default ACL
- The operation was not simple creation
- The program asked for less
- Check your understanding
- Servers Academy — Key Takeaway
- Official references
How Linux umask sets initial permissions
A program asks the kernel to create a file or directory with a particular mode: the permission bits it wants. The kernel applies the creating process’s umask to that request. The resulting mode becomes part of the new filesystem object.
For a new ordinary file, a program commonly requests
0666: read and write for owner, group and others.
Plain directory creation commonly starts with 0777,
including the execute bit needed to traverse a directory.
The leading zero marks these as octal values.
The file tiles use owner, group and other columns. Rows represent read, write and execute. A cross marks an unset permission.
-
Program requests
0666
rw-rw-rw-An ordinary file starts with requested read and write bits.
-
Process mask clears
0022
group: w · other: wRemove write permission from the group and other classes.
-
New file receives
0644
rw-r--r--The owner keeps write permission; the other classes keep read.
This also explains why umask 000 does not make an
ordinary text file executable. If the program requested
0666, there were no execute bits to keep. Likewise,
a program requesting 0600 still gets
0600 with a mask of 022.
Reading 022, 027 and 077
The last three mask digits refer to owner, group and others.
Within each digit, read is 4, write is
2 and execute is 1. In a mask,
set bits identify permissions to remove.
For example, 027 removes nothing from the owner,
write from the group, and all three bits from others. The final
result still depends on what the program requested.
| Mask | File request 0666 | Directory request 0777 | Effect on these requests |
|---|---|---|---|
022 |
0644rw-r--r--
|
0755rwxr-xr-x
|
Group and others lose write. |
027 |
0640rw-r-----
|
0750rwxr-x---
|
Group loses write; others lose all bits. |
077 |
0600rw-------
|
0700rwx------
|
Group and others lose all bits. |
The table assumes ordinary creation without a default ACL or a
later permission change. These masks express different sharing
requirements; 077 may suit private output but prevent
a separate service account from reading a generated file.
Use a bitwise filter, not subtraction
The ampersand means bitwise AND; the tilde inverts the mask’s bits. Keep a requested permission only when the corresponding mask bit is clear.
0666 & ~0022 = 0644
0777 & ~0022 = 0755
Subtraction happens to work for some familiar examples, but it
is the wrong general rule. A mask of 033 applied
to 0666 produces 0644, not the
0633 that octal subtraction would suggest.
Clearing an execute bit that was already absent cannot borrow
from a read or write bit.
Try two masks without changing your login shell
In Bash, these read-only commands show the current shell’s mask:
umask
umask -S
Numeric output might be 0022. The
symbolic form
for that mask is u=rwx,g=rx,o=rx: it describes the
permissions the mask allows, before a program’s requested mode
limits them. It is not a promise that newly created files get
execute permission.
The next block creates a temporary workspace and four disposable
objects. Parentheses run it in a subshell, so its mask changes
do not alter the surrounding shell. Use Bash and the ordinary
mktemp, mkdir and ls
utilities; no root access is needed.
(
set -eu
umask 077
mask_lab=$(mktemp -d "${TMPDIR:-/tmp}/sa-umask.XXXXXX")
printf 'Workspace: %s\n' "$mask_lab"
umask 022
printf 'Created under 022\n' > "$mask_lab/shared.txt"
mkdir "$mask_lab/shared-dir"
umask 077
printf 'Created under 077\n' > "$mask_lab/private.txt"
mkdir "$mask_lab/private-dir"
ls -ld "$mask_lab/shared.txt" "$mask_lab/shared-dir" \
"$mask_lab/private.txt" "$mask_lab/private-dir"
)
On a filesystem directory without an inherited default ACL,
inspect the permission strings: shared.txt should
be -rw-r--r-- and shared-dir should be
drwxr-xr-x. The private pair should be
-rw------- and drwx------.
Names, timestamps and ownership labels depend on your machine.
Notice that the shared pair retains its earlier permissions
even though the subshell switched to 077 before
listing everything. Run umask again after the block;
your surrounding shell should still have its original mask.
Why a service can differ from your terminal
The mask belongs to a process, rather than being a single permission preference attached to an account. Child processes inherit it, and executing another program preserves it unless something changes the setting.
Your shell therefore passes its current mask to programs it launches. A background service may be launched through a different parent and configuration. Using the same user name does not make those creation contexts identical.
For a systemd-managed service,
UMask=
is the execution setting to investigate. It belongs in the
service’s configuration, as described in
the guide to systemd service units.
The running program can still choose a more restrictive creation
mode or change its own mask.
To inspect your current Bash process on a modern Linux system with a mounted proc filesystem:
awk '/^Umask:/{print}' "/proc/$$/status"
The Umask: field reports that process’s mask.
Here $$ identifies the Bash shell. A different
process must be inspected using its own PID, subject to local
access restrictions. The field is available on Linux 4.7 and later.
When the mask does not explain the whole result
The parent directory has a default ACL
An access control list, or ACL, can express permissions for additional users and groups. A directory’s default ACL supplies inherited access rules for new children. On Linux, that inheritance path replaces the ordinary umask calculation; the requested mode still limits which permissions can survive.
The read-only getfacl utility displays those rules.
Look for entries beginning with default: on the
parent directory. An ACL’s mask:: entry is a
different mechanism from the process umask, despite the similar name.
The operation was not simple creation
Opening an existing file does not recreate its initial permissions. An editor may instead save through a temporary file and rename it. A copy or extraction tool may preserve recorded modes or apply additional permission changes. Inspect what the operation actually did before blaming the shell’s mask.
This matters during recovery. The Linux backup restore test uses tar options that let the current umask limit restored permissions. Matching file contents and matching permissions remain separate checks.
The program asked for less
If a secret-writing tool explicitly requests 0600,
choosing a more permissive mask cannot add group read access.
Find the requested mode and any later permission changes.
Avoid replacing a targeted investigation with a global mask
change or a broad chmod.
Check your understanding
Why does mask 022 often produce files with 644 but directories with 755?
The ordinary requests differ: 0666 for a file and 0777 for a directory. The same mask removes group and other write bits from each. It does not create missing execute bits.
Will setting umask 077 make yesterday’s readable files private?
No. Changing a process’s creation mask does not rewrite existing files. Inspect their actual permissions and access requirements before planning any targeted change.
A program requests 0600 under mask 022. What is the resulting mode?
0600, on the ordinary creation path. The mask removes permissions; it cannot supply read or write bits absent from the request.
Why might a service and your shell create different modes under the same account?
They are different processes with potentially different inherited masks, service settings and requested modes. Compare the creation contexts instead of relying on the account name.
The parent has a default ACL. Can you use the simple umask table as a guarantee?
No. Inspect the parent’s inherited access rules and the program’s requested mode. Default ACL inheritance changes the creation path on Linux.








