systems

Resolving 'bash: permission denied' on macOS: causes and fixes

On macOS, encountering the message bash: permission denied typically means the account you are using cannot execute the target file from Bash. This is often a permissions, owner...

Mara Ellison
Resolving 'bash: permission denied' on macOS: causes and fixes

On macOS, encountering the message bash: permission denied typically means the account you are using cannot execute the target file from Bash. This is often a permissions, ownership, or system security policy issue rather than a Bash bug. This guide explains the common causes, how to safely inspect and fix permissions, the role of System Integrity Protection (SIP), and best practices to avoid breaking system tools. The aim is to give you an evergreen, fact-first workflow you can apply to scripts, binaries, and installed tools.

Understanding the error message and context

When Bash reports bash: permission denied, it means the process identified by your user ID cannot read and execute the file you requested. This can occur with shell scripts, compiled binaries, or any executable file. Unlike some error messages that are ambiguous, this one directly points to execution permission issues and access controls. Common triggers include running a downloaded script without marking it as executable, editing system tools without admin rights, or interacting with files owned by another user. Recognizing this as a permissions and security control problem is the first step toward a safe fix.

File permissions and ownership on macOS

macOS uses Unix-style permissions to control who can read, write, or execute a file. Every file has an owner, a group, and other users, each with specific permission bits. When you run a command, Bash checks these bits and your user identity to decide whether to allow access. If the execute bit is missing for your user category, or if ownership restricts execution, Bash returns permission denied. Knowing how to read and modify these bits safely is essential for both everyday scripts and system-level binaries.

Checking current permissions and ownership

Use ls -l in Terminal to see permissions, owner, and group for any file. The first character indicates the file type, followed by three groups of three characters for owner, group, and others, showing read (r), write (w), and execute (x) status. To see macOS-specific attributes like the quarantine attribute, prepend xattr -l to the path. Below is a concise reference table you can use to map the numeric codes, permission symbols, and their meanings.

Read, no write, no execute
Numeric mode Symbolic permissions Meaning
7 rwx Read, write, execute
6 rw- Read, write, no execute
5 r-x Read, execute, no write
4 r--

For a script like /Users/you/myscript.sh, you can inspect with:

  • ls -l /Users/you/myscript.sh to view permissions and owner.
  • xattr -l /Users/you/myscript.sh to check quarantine attributes.

How to add execute permission safely

If the file is missing execute permission for your user, you can add it with chmod. For a user-owned script, a common safe approach is to enable user execute only:

  • chmod u+x ~/myscript.sh allows only you to execute it.
  • chmod +x ~/myscript.sh allows all categories to execute, which is less restrictive.

Use the more restrictive option whenever possible to reduce unintended execution risks. Always verify the script contents before adding execute permission, especially for files obtained from untrusted sources.

macOS System Integrity Protection (SIP) and its effects

System Integrity Protection (SIP) is a macOS security technology that limits what even privileged users can modify in protected system locations, such as /usr, /bin, /sbin, and /private. SIP is active by default and can cause bash: permission denied when Bash tries to run a system binary that has been altered or replaced by another tool, such as certain language runtimes or third-party shells. SIP protects integrity but may interfere with legitimate developer workflows involving system directories.

How to check SIP status

To see whether SIP is active, restart your Mac and hold Command-R to enter Recovery, open Terminal, and run:

  • csrutil status

You will see one of the following, which are informational, not errors:

  • System Integrity Protection status: enabled.
  • System Integrity Protection status: disabled.

Notes:

  • You cannot disable SIP permanently from Recovery; you can only temporarily disable it for a single restart.
  • Disabling SIP is not recommended for security and stability reasons.

Common scenarios and safe solutions

Below are recurring situations that trigger bash: permission denied, along with secure, actionable fixes.

Running a downloaded script

When you download a shell script, macOS may mark it as unsafe. You can verify and fix this by:

  • Checking with ls -l to confirm the lack of execute permission.
  • Removing quarantine with xattr -d com.apple.quarantine /path/to/script.
  • Adding execute permission safely for your user only: chmod u+x /path/to/script.

Modifying system-managed tools

Editing or replacing files in /usr/bin or /bin can trigger SIP denials. Instead, install language runtimes and tools in user-owned locations, such as /usr/local or via a package manager like Homebrew, which follow macOS conventions. If you must work near system directories, consider using virtual environments or containers to isolate changes.

Using an editor or IDE that changes file ownership

Some GUI editors may save files as root or alter ownership unintentionally. Verify with ls -l and, if needed, correct ownership with sudo chown $(whoami) /path/to/file. Prefer command-line editors or configure your editor to preserve your user ownership.

Best practices to avoid future 'permission denied' issues

Adopting a few habits can save you from repeated troubleshooting and help keep your system stable.

  • Avoid using sudo or root to run everyday Bash commands or scripts.
  • Download scripts from trusted sources and review them before execution.
  • Prefer user-level installations for development tools (e.g., Homebrew, asdf, nvm).
  • Understand the difference between system directories and user-writable locations.
  • Use quarantine management and execute permission changes deliberately, not by habit.

When to seek additional help

If the issue persists after verifying permissions, quarantine flags, and SIP status, consider the following:

  • Check Console.app for related security or system logs.
  • Confirm the file is not corrupted or intended for a different architecture.
  • Verify that your user account has the necessary parent directory execute permissions to traverse the path.
  • Consult documentation for the specific tool or script author, as some installers have platform-specific requirements.

Summary and quick cheat sheet

  • Diagnose: Run ls -l and check ownership and execute bits.
  • Fix permissions: Use chmod u+x file for user-owned scripts.
  • Quarantine: Remove with xattr -d com.apple.quarantine file when appropriate.
  • SIP awareness: SIP protects system files; avoid disabling it and prefer user-space tooling.
  • Tooling: Install development tools in user-owned paths to stay clear of SIP-protected locations.

Related Reading

More pages in this topic cluster.

Essential Basic Shell Commands Reference

Mastering basic shell commands is foundational for efficient, reliable work on Unix-like systems. This reference covers navigation, file manipulation, permissions, processes, pi...

Read next
How to Create Files From the Linux Command Line

Creating files from the Linux command line is a foundational skill that supports scripting, automation, and efficient system administration. Whether you are building configurati...

Read next
How to Set a Restore Point

At its simplest, a restore point is a timestamped snapshot of your system files, registry, and installed programs that Windows can use to return your computer to a previous stab...

Read next