chmod +x: Making a File Executable and the umask Catch
chmod +x adds the execute bit so a file can be run. Written without a class it means all three classes masked by the umask, so chmod u+x or chmod a+x is the unambiguous form when the result matters.
At a glance
- What it does
- Adds the execute bit without changing read or write
- Without a class
- Equivalent to a+x with the umask applied, so a tight umask limits it to the owner
- chmod u+x
- Owner only, unambiguous, unaffected by the umask
- Typical result
- 644 becomes 755 with chmod a+x, or 744 with chmod u+x
- Scripts also need read
- The interpreter reads the file, so execute without read fails for a shell or Python script
- Version control
- Git records only the owner execute bit, as mode 100755 against 100644
In detail
chmod +x is the first command anyone learns after writing a script, and it is one of the few places where symbolic notation is clearly better than octal: it adds the execute bit and leaves read and write exactly as they were. A file at 644 becomes 755, a file at 640 becomes 750, and you did not have to know which it was.
The catch is that omitting the class makes it depend on the umask. POSIX says a bare plus applies to all three classes with the umask subtracted, so under the common 022 you get a+x as expected, and under a tight 077 you get owner execute only. On a shared machine where the umask is set for privacy, chmod +x quietly does less than the person typing it intended.
Execute alone is not enough for a script. The kernel reads the first line to find the interpreter, and the interpreter then reads the whole file, so a script needs the read bit for whoever runs it. A file at 711 is executable and unreadable, which works for a compiled binary and gives permission denied for a shell script, and that error names the script rather than the missing read bit.
The other half of a working script is the interpreter line. Without a shebang as the first line of the file, an execute attempt either fails or falls back to the calling shell, which is why a Python script with the execute bit set can still produce syntax errors from a shell. Adding the shebang and the execute bit together is the reliable pair.
Version control only records part of this. Git tracks a single executable bit, storing a file as mode 100644 or 100755, and ignores the rest of the mode entirely. To set it without touching your working copy's permissions, use git update-index with the chmod flag, which is also the way to fix a file that arrived from a system that does not carry permissions at all.
Examples
chmod +x deploy.sh # all three classes, masked by the umask
chmod a+x deploy.sh # all three classes, explicitly
chmod u+x deploy.sh # owner only
chmod 755 deploy.sh # set the whole mode at once$ chmod 711 build.sh
$ ./build.sh
bash: ./build.sh: Permission denied
$ chmod 755 build.sh
$ ./build.sh
building ...git update-index --chmod=+x scripts/deploy.sh
git commit -m "chore: mark deploy script executable"
# git stores only two modes for a regular file
100644 not executable
100755 executableThings that catch people out
- chmod +x without a class is affected by the umask. Under a private umask it adds execute for the owner only, which looks like the command silently failed for everyone else.
- A script needs read permission for whoever runs it. Execute without read works for compiled binaries and never for interpreted files.
- Adding the execute bit does not add a shebang. Without an interpreter line the file may be run by the calling shell, producing errors that have nothing to do with permissions.
- Checking out a repository on a file system that does not carry permissions loses the executable bit. Set core.fileMode appropriately or restore the bit with git update-index rather than committing a mode change every time.
Try it: Chmod Calculator
Tick the nine permission boxes, or type an octal or symbolic value, and get the three digit and four digit octal, the ls -l rendering and the exact chmod command back.
Chmod Calculator
LOCAL · Browser-OnlyCalculate Unix file permissions with an interactive chmod builder
Permission Matrix
| Entity | Read (4) | Write (2) | Execute (1) | Octal | Symbolic |
|---|---|---|---|---|---|
| Owner (u) | 7 | rwx | |||
| Group (g) | 5 | r-x | |||
| Others (o) | 5 | r-x |
Special Bits
Advanced permission flags for executables and directories
Generated Permissions
755rwxr-xr-x-rwxr-xr-xchmod 755 filenamechmod u=rwx,g=rx,o=rx filenamePermission Breakdown
Owner (u)
7rwx- - Read files / list directory contents
- - Write / modify / delete
- - Execute / traverse directory
Group (g)
5r-x- - Read files / list directory contents
- - Execute / traverse directory
Others (o)
5r-x- - Read files / list directory contents
- - Execute / traverse directory
Common Permissions Reference
| Octal | Symbolic | Meaning |
|---|---|---|
777 | rwxrwxrwx | Full access for everyone |
755 | rwxr-xr-x | Owner full, others read and execute |
750 | rwxr-x--- | Owner full, group read and execute |
700 | rwx------ | Owner full access only |
666 | rw-rw-rw- | Read and write for everyone |
644 | rw-r--r-- | Owner read/write, others read only |
600 | rw------- | Owner read/write only |
555 | r-xr-xr-x | Read and execute for everyone |
444 | r--r--r-- | Read only for everyone |
400 | r-------- | Owner read only |
Related File permissions
All file permissions →chmod 644: The Default File Mode and When to Change It
644 gives the owner read and write and everyone else read only. Why it is the default for files under a 022 umask, and the cases where it is wrong.
chmod 755: The Standard Mode for Directories and Programs
755 gives the owner full control and everyone else read and execute. Why it is right for directories and executables and wrong for ordinary data files.
Symbolic chmod Notation: u, g, o, a With Plus, Minus and Equals
Symbolic mode changes one class at a time instead of setting all nine bits. How plus, minus and equals differ, and what the capital X form is for.
umask: How the Default Mode of a New File Is Decided
umask removes permission bits from newly created files and directories. Why 022 gives 644 and 755, and why a new file is never executable.
How to Read an ls -l Permission String Such as rwxr-xr-x
The ten characters at the start of an ls -l line decode to a file type and three permission classes. What s, S, t, T and a trailing plus mean.
chmod 777: Everyone Gets Everything
777 gives read, write and execute to the owner, the group and everyone else. What it actually allows, why it is never the real fix, and what to use instead.
Tools for this
- Chmod Calculator Free online chmod calculator - calculate Unix file permissions with an interactive chmod builder