Commandchmod

Make a script executable

Adds the executable permission bit to a script for its owner, group and others alike, without touching any of its existing read/write bits.

Last updated

Commandchmod
chmod +x deploy.sh

How it works

A bare +x means a+x masked by your umask — with the usual umask 022 that is owner, group and others; under a stricter umask like 077 it sets owner only. Write a+x explicitly if you genuinely mean all three. Either way it leaves existing read and write bits alone, which is the main reason to prefer it over an absolute mode like chmod 755: 755 REPLACES the whole permission set and can silently change bits you didn't intend to touch.

Once set, ./deploy.sh runs the file directly instead of needing bash deploy.sh — the shell resolves the leading #! (shebang) line to know which interpreter to launch it with.

Watch out for

  • →Without a shebang (#!/bin/bash, #!/usr/bin/env python3) the kernel refuses the file and your shell quietly falls back to running it with sh — so ./deploy.sh usually "works" while ignoring that you wrote bash- or Python-specific code. Anything launching it outside a shell (execve, Python's subprocess without shell=True, some CI runners) fails outright. Always include one.
  • →To grant execute permission to just yourself rather than everyone, use chmod u+x deploy.sh instead of the broader +x shown here — worth doing for anything containing credentials or logic you don't want other local users running.
  • →This has no equivalent on native Windows filesystems (NTFS has no Unix permission bits at all) — under WSL or Git Bash the bit is tracked, but it doesn't reliably survive a copy back out to native Windows tooling, where executability is inferred from the file extension instead.

Part by part

+x
Add the execute bit. The plus adds a permission without disturbing the others, unlike a numeric mode which replaces all of them.
deploy.sh
The target. chmod acts on the file itself, not on its contents, so nothing about the script changes.

Common mistakes

  • chmod 777 deploy.sh

    Grants everyone read, write and execute. It makes the script work and also lets any user on the machine rewrite what it does, which on a shared or server system is a genuine security hole rather than a stylistic one.

    chmod +x deploy.sh
  • chmod +x *.sh

    Fine when you meant it, and a surprise when the glob catches a file you had not considered. Prefer naming files explicitly, or check with echo first if the list is long.

  • chmod -R +x .

    Recursively marks every file executable, including data, images and source files. Use find with -type f and a name filter instead, so only the intended files are touched.

Questions

Who gets the execute bit with +x?

Owner, group and others — but masked by your umask, so a umask of 022 typically yields owner, group and other while 077 yields owner only. Use u+x to be explicit about it rather than relying on the default.

Why does my script still say permission denied?

If the bit is set, the next suspects are the filesystem being mounted noexec, or a missing or wrong shebang line. Run it explicitly with bash script.sh to distinguish an interpreter problem from a permission one.

Does git preserve the executable bit?

Yes, it tracks that one permission bit and nothing else. That is why a script committed from Windows often arrives non-executable, and git update-index --chmod=+x fixes it in the index.

What do the numeric modes mean?

Each digit is a sum: 4 read, 2 write, 1 execute, for owner, group and others in turn. 755 is the usual choice for a script — full control for the owner, read and execute for everyone else.

Related in Commands