Top Tags

Fix permissions on Mac for Midnight Commander install by Brew

A quick guide to fix permissions issues on Mac when installing Midnight Commander via Homebrew.

Overview

Midnight Commander (mc) is a visual file manager for Unix-like systems that provides a dual-pane interface similar to Norton Commander. On macOS, permission conflicts commonly arise when mc attempts to write to XDG Base Directory specification paths (~/.config, ~/.local/share, ~/.cache) that were created by other processes or during system migrations.

Understanding the Permission Model

macOS combines traditional POSIX permissions (user/group/other rwx) with ACLs (Access Control Lists) and System Integrity Protection (SIP). When Midnight Commander runs, it needs:

  • Read/Write access to ~/.config/mc/ for configuration files (ini, panels)
  • Write access to ~/.local/share/mc/ for command history and hotlist
  • Write access to ~/.cache/mc/ for temporary files and thumbnails

Permission issues typically manifest as:

  • Cannot write to ~/.config/mc/ini errors
  • Loss of panel history between sessions
  • Command history not persisting
  • Exit code 1 without clear error messages

Common root causes:

  1. UID mismatch: Directories created by sudo operations (owned by root:wheel)
  2. Migration artifacts: Files from Time Machine restore with incorrect ownership
  3. Shared system use: Multiple admin users creating conflicting ownership
  4. ACL overrides: Extended attributes taking precedence over POSIX bits

Install Midnight Commander via Homebrew

bash
1brew install midnight-commander

Fix Permissions Issues

bash
1sudo chown -R $(whoami) /Users/$(whoami)/.local
2sudo chown -R $(whoami) /Users/$(whoami)/.cache
3sudo chown -R $(whoami) /Users/$(whoami)/.config

Why this happens

Homebrew installs Midnight Commander into /opt/homebrew (Apple Silicon) or /usr/local (Intel) and expects your user to own the config and cache paths that mc writes to. If these directories were created by another UID (migration, sudo, Time Machine restore), mc cannot write its history or panels state, so it exits with permission errors. The chown commands above restore ownership so mc can persist its runtime files.

Technical Deep Dive: XDG Base Directory Specification

Midnight Commander follows the XDG Base Directory specification for locating configuration and data files:

Environment VariableDefault PathMC Usage
$XDG_CONFIG_HOME~/.configStores ini, panels.ini, layout.ini
$XDG_DATA_HOME~/.local/shareCommand history, hotlist, filepos
$XDG_CACHE_HOME~/.cacheTree cache, thumbnails, temporary files

Understanding the Output

The ls -le output includes extended attributes marked with @ and ACLs marked with +:

drwxr-xr-x+ 5 username staff 160 Feb 1 10:30 .config 0: group:everyone deny delete

The + suffix indicates ACL presence. The stat command shows numeric UID/GID and symbolic mode.

Common ACL entries on macOS:

  • group:everyone deny delete - prevents accidental deletion
  • user:root allow list,search,readattr - allows system processes to read
  • group:wheel allow read - admin group read access

If you see unknown ACL entries, you can drop them (use cautiously):

bash
1chmod -RN ~/.local ~/.cache ~/.config

Alternative: Surgical ACL Removal

Instead of removing all ACLs, target specific entries:

bash
1# List all ACLs in detail
2ls -led ~/.config/mc
3
4# Remove specific ACL entry (example: removing entry 0)
5chmod -a# 0 ~/.config/mc
6
7# Add explicit user permission via ACL (if needed)
8chmod +a "user:$(whoami) allow read,write,execute,delete,append,readattr,writeattr,readextattr,writeextattr" ~/.config/mc
9
10```bash
11# Example of correct ownership (user owns, group=staff)
12drwxr-xr-x 5 username staff 160 Feb 1 10:30 .config
13
14# Problematic state after sudo operation (root owns)
15drwxr--prefix
16brew list --versions midnight-commander

Interpreting Homebrew Paths

Apple Silicon Macs (M1/M2/M3/M4):

  • Homebrew prefix: /opt/homebrew
  • Binaries: /opt/homebrew/bin/mc
  • Cellar location: /opt/homebrew/Cellar/midnight-commander/VERSION

Intel Macs:

What This Command Does

diskutil resetUserPermissions performs a comprehensive ownership reset:

  1. Recursively walks /Users/username and all subdirectories
  2. Resets ownership of all files to match the UID provided
  3. Preserves group membership (typically staff)
  4. Fixes ACLs by removing inherited entries that conflict with POSIX

Advanced Configuration Management

For persistent configuration across shell sessions, add to your shell profile:

bash
1# ~/.zshrc or ~/.bashrc
2export MC_CONFIG_DIR="$HOME/dotfiles/mc/config"
3export MC_DATA_DIR="$HOME/dotfiles/mc/data"
4export MC_CACHE_DIR="$HOME/.cache/mc"
5
6# Optional: create directories if they don't exist
7[[ ! -d "$MC_CONFIG_DIR" ]] && mkdir -p "$MC_CONFIG_DIR"
8[[ ! -d "$MC_DATA_DIR" ]] && mkdir -p "$MC_DATA_DIR"

Environment Variables Reference

Midnight Commander respects these environment variables (in order of precedence):

VariablePurposeDefault Fallback
MC_CONFIG_DIRConfiguration files location$XDG_CONFIG_HOME/mc or ~/.config/mc
MC_DATA_DIRUser data (history, hotlist)$XDG_DATA_HOME/mc or ~/.local/share/mc
MC_CACHE_DIRCache files$XDG_CACHE_HOME/mc or ~/.cache/mc
MC_SKINColor scheme filedefault
MC_PROFILE_ENABLEDEnable profiling(unset)

Symlinking Configuration for Version Control

Keep mc configuration in a git-tracked dotfiles repository:

bash
1# Assuming dotfiles repo at ~/dotfiles
2mkdir -p ~/dotfiles/mc/config ~/dotfiles/mc/data
3
4# Backup existing config
5[[ -d ~/.config/mc ]] && cp -r ~/.config/mc ~/.config/mc.backup
6
7# Create symlinks
8ln -sf ~/dotfiles/mc/config ~/.config/mc
9ln -sf ~/dotfiles/mc/data ~/.local/share/mc
10
11# Add to git
12cd ~/dotfiles
13git add mc/
14git commit -m "Add Midnight Commander configuration"

Debugging Configuration Loading

Verify which config files mc is actually reading:

bash
1# Launch mc with profiling to see file access
2MC_PROFILE_ENABLED=1 mc 2>&1 | grep "config"
3
4# Or use fs_usage (requires sudo, generates lots of output)
5sudo fs_usage -f filesys -w mc | grep -E "(config|ini|panels)"

Sample Configuration Files

~/.config/mc/ini (key bindings and settings):

ini
1[Midnight-Commander]
2use_internal_edit=true
3use_internal_view=true
4auto_save_setup=true
5preallocate_space=false
6auto_menu=false
7drop_menus=false
8shell_patterns=true
9confirm_delete=true
10confirm_overwrite=true

~/.config/mc/panels.ini (panel layout):

ini
1[New Left Panel]
2display=listing
3reverse=false
4case_sensitive=true
5exec_first=false
6
7[New Right Panel]
8display=listing
9reverse=false
10case_sensitive=true
11exec_first=false

Verification and Testing

After applying permission fixes, verify mc works correctly:

bash
1# Test basic launch
2mc --version && echo "MC binary accessible"
3
4# Test config write
5mc -F 2>&1 | grep -i "permission\|error" || echo "No permission errors"
6
7# Check runtime files exist
8ls -la ~/.config/mc/ ~/.local/share/mc/
9
10# Test history persistence
11mc -c "cd /tmp && exit"
12grep -q "/tmp" ~/.local/share/mc/history 2>/dev/null && echo "History persisted successfully"

Prevention: Best Practices

  1. Avoid using sudo for home directory operations

    bash
    1# ❌ Wrong - creates root-owned files
    2sudo vim ~/.config/myapp/config.ini
    3
    4# ✅ Correct - regular user
    5vim ~/.config/myapp/config.ini
  2. Set correct umask to ensure new files have proper permissions:

    bash
    1# Add to ~/.zshrc or ~/.bashrc
    2umask 022 # New files: rw-r--r--, directories: rwxr-xr-x
  3. Use Time Machine backup carefully - restore to same username when possible

  4. Regular permission audits:

    bash
    1# Weekly check for root-owned files in home directory
    2find ~ -user root -ls 2>/dev/null | grep -v "/Library/"

Common Error Messages and Solutions

| Error Message | Root Cause | Solution | | ---------------------------------- | ---------------------- | ----------------------------------------- | -------------------------------------------------------------------------- | | Cannot write to ~/.config/mc/ini | Wrong ownership | chown -R $(whoami) ~/.config | | Permission denied on panel save | ACL blocking write | chmod -RN ~/.config/mc | | No such file or directory | Missing XDG dirs | mkdir -p ~/.config/mc ~/.local/share/mc | | mc exits immediately with code 1 | Cache dir not writable | chown -R $(whoami) ~/.cache | Respects SIP-protected paths like ~/Library/Saved Application State/ |

Timing: On a 500GB home directory, expect 10-30 minutes. The operation is non-destructive to file contents but modifies metadata.

When to use:

  • After restoring from Time Machine backup
  • After system migration or disk clone
  • When multiple applications report permission errors
  • If sudo was used extensively for home directory operations

Warning signs indicating you need this:

bash
1# Multiple apps cannot write to home directory
2touch ~/test.txt
3# Permission denied
4
5# Even new files show wrong ownership
6ls -l ~/test.txt
7# -rw-r--r-- 1 root staff 0 Feb 1 10:30 test.txt

SIP (System Integrity Protection) Considerations

If the command fails with "Operation not permitted," SIP may be blocking it. Check SIP status:

bash
1csrutil status
2# System Integrity Protection status: enabled.

To run diskutil resetUserPermissions with SIP enabled:

  1. Reboot into Recovery Mode (hold Cmd+R on Intel, hold Power on Apple Silicon)
  2. Open Terminal from Utilities menu
  3. Mount your volume (if not auto-mounted):
    bash
    1diskutil list
    2diskutil mount disk1s1 # adjust disk identifier
  4. Run the reset:
    bash
    1diskutil resetUserPermissions /Volumes/Macintosh\ HD $(dscl /Volumes/Macintosh\ HD/var/db/dslocal/nodes/Default -read /Users/username UniqueID | awk '{print $2}')
  5. Reboot normally

Do not disable SIP unless absolutely necessary, as it protects critical system files.

  • Homebrew prefix: /usr/local
  • Binaries: /usr/local/bin/mc
  • Cellar location: /usr/local/Cellar/midnight-commander/VERSION

Verify mc is in your PATH:

bash
1which mc
2# Should output: /opt/homebrew/bin/mc (Apple Silicon) or /usr/local/bin/mc (Intel)
3
4# Check if mc can see its own info
5mc --version

Troubleshooting Multiple Homebrew Installations

If you've migrated from Intel to Apple Silicon or have both installations:

bash
1# List all mc binaries
2find /usr/local /opt/homebrew -name mc -type f 2>/dev/null
3
4# Check PATH precedence
5echo $PATH | tr ':' '\n' | nl
6
7# Force use of specific installation
8/opt/homebrew/bin/mc # Apple Silicon
9/usr/local/bin/mc # Intelb 1 10:30 .config
10
11# Mixed ownership (parent OK, child broken)
12drwxr-xr-x 5 username staff 160 Feb 1 10:30 .config
13drwxr-xr-x 3 root wheel 96 Feb 1 10:31 .config/mc

The chown -R recursive flag ensures all subdirectories and files inherit correct ownership.

Check current ownership and ACLs

Run a quick inspection before and after the fix to confirm ownership and to spot unexpected ACL entries that may override POSIX permissions:

bash
1ls -le ~/.local ~/.cache ~/.config
2stat -f "%N uid=%u gid=%g mode=%Sp" ~/.local ~/.cache ~/.config

If you see unknown ACL entries, you can drop them (use cautiously):

bash
1chmod -RN ~/.local ~/.cache ~/.config

Homebrew health check

Ensure your Homebrew prefix and environment are consistent, and that mc is installed where you expect:

bash
1brew doctor
2brew --prefix midnight-commander
3brew list --versions midnight-commander

Last-resort: reset user permissions on the volume

When multiple apps show similar home-directory permission issues, reset your account permissions on the system volume (macOS 10.13+):

bash
1sudo diskutil resetUserPermissions / $(id -u)

Run it from Recovery if SIP blocks the command. Afterward, re-run the chown steps above for your dot-directories.

Optional: isolate Midnight Commander config

If you prefer to keep mc config in a dedicated path (e.g., inside a synced dotfiles repo), point MC_CONFIG_DIR and MC_DATA_DIR before launching:

bash
1export MC_CONFIG_DIR="$HOME/.config/mc"
2export MC_DATA_DIR="$HOME/.local/share/mc"
3mc