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/inierrors- Loss of panel history between sessions
- Command history not persisting
- Exit code 1 without clear error messages
Common root causes:
- UID mismatch: Directories created by
sudooperations (owned by root:wheel) - Migration artifacts: Files from Time Machine restore with incorrect ownership
- Shared system use: Multiple admin users creating conflicting ownership
- ACL overrides: Extended attributes taking precedence over POSIX bits
Install Midnight Commander via Homebrew
1brew install midnight-commanderFix Permissions Issues
1sudo chown -R $(whoami) /Users/$(whoami)/.local2sudo chown -R $(whoami) /Users/$(whoami)/.cache3sudo chown -R $(whoami) /Users/$(whoami)/.configWhy 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 Variable | Default Path | MC Usage |
|---|---|---|
$XDG_CONFIG_HOME | ~/.config | Stores ini, panels.ini, layout.ini |
$XDG_DATA_HOME | ~/.local/share | Command history, hotlist, filepos |
$XDG_CACHE_HOME | ~/.cache | Tree 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 deletionuser:root allow list,search,readattr- allows system processes to readgroup:wheel allow read- admin group read access
If you see unknown ACL entries, you can drop them (use cautiously):
1chmod -RN ~/.local ~/.cache ~/.configAlternative: Surgical ACL Removal
Instead of removing all ACLs, target specific entries:
1# List all ACLs in detail2ls -led ~/.config/mc3
4# Remove specific ACL entry (example: removing entry 0)5chmod -a# 0 ~/.config/mc6
7# Add explicit user permission via ACL (if needed)8chmod +a "user:$(whoami) allow read,write,execute,delete,append,readattr,writeattr,readextattr,writeextattr" ~/.config/mc9
10```bash11# Example of correct ownership (user owns, group=staff)12drwxr-xr-x 5 username staff 160 Feb 1 10:30 .config13
14# Problematic state after sudo operation (root owns)15drwxr--prefix16brew list --versions midnight-commanderInterpreting 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:
- Recursively walks
/Users/usernameand all subdirectories - Resets ownership of all files to match the UID provided
- Preserves group membership (typically
staff) - Fixes ACLs by removing inherited entries that conflict with POSIX
Advanced Configuration Management
For persistent configuration across shell sessions, add to your shell profile:
1# ~/.zshrc or ~/.bashrc2export 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 exist7[[ ! -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):
| Variable | Purpose | Default Fallback |
|---|---|---|
MC_CONFIG_DIR | Configuration files location | $XDG_CONFIG_HOME/mc or ~/.config/mc |
MC_DATA_DIR | User data (history, hotlist) | $XDG_DATA_HOME/mc or ~/.local/share/mc |
MC_CACHE_DIR | Cache files | $XDG_CACHE_HOME/mc or ~/.cache/mc |
MC_SKIN | Color scheme file | default |
MC_PROFILE_ENABLED | Enable profiling | (unset) |
Symlinking Configuration for Version Control
Keep mc configuration in a git-tracked dotfiles repository:
1# Assuming dotfiles repo at ~/dotfiles2mkdir -p ~/dotfiles/mc/config ~/dotfiles/mc/data3
4# Backup existing config5[[ -d ~/.config/mc ]] && cp -r ~/.config/mc ~/.config/mc.backup6
7# Create symlinks8ln -sf ~/dotfiles/mc/config ~/.config/mc9ln -sf ~/dotfiles/mc/data ~/.local/share/mc10
11# Add to git12cd ~/dotfiles13git add mc/14git commit -m "Add Midnight Commander configuration"Debugging Configuration Loading
Verify which config files mc is actually reading:
1# Launch mc with profiling to see file access2MC_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):
1[Midnight-Commander]2use_internal_edit=true3use_internal_view=true4auto_save_setup=true5preallocate_space=false6auto_menu=false7drop_menus=false8shell_patterns=true9confirm_delete=true10confirm_overwrite=true~/.config/mc/panels.ini (panel layout):
1[New Left Panel]2display=listing3reverse=false4case_sensitive=true5exec_first=false6
7[New Right Panel]8display=listing9reverse=false10case_sensitive=true11exec_first=falseVerification and Testing
After applying permission fixes, verify mc works correctly:
1# Test basic launch2mc --version && echo "MC binary accessible"3
4# Test config write5mc -F 2>&1 | grep -i "permission\|error" || echo "No permission errors"6
7# Check runtime files exist8ls -la ~/.config/mc/ ~/.local/share/mc/9
10# Test history persistence11mc -c "cd /tmp && exit"12grep -q "/tmp" ~/.local/share/mc/history 2>/dev/null && echo "History persisted successfully"Prevention: Best Practices
-
Avoid using sudo for home directory operations
bash1# ❌ Wrong - creates root-owned files2sudo vim ~/.config/myapp/config.ini34# ✅ Correct - regular user5vim ~/.config/myapp/config.ini -
Set correct umask to ensure new files have proper permissions:
bash1# Add to ~/.zshrc or ~/.bashrc2umask 022 # New files: rw-r--r--, directories: rwxr-xr-x -
Use Time Machine backup carefully - restore to same username when possible
-
Regular permission audits:
bash1# Weekly check for root-owned files in home directory2find ~ -user root -ls 2>/dev/null | grep -v "/Library/"
Related Issues and Resources
- macOS SIP documentation:
man csrutil - Homebrew troubleshooting:
brew doctoroutput explanation at docs.brew.sh - XDG Base Directory spec: specifications.freedesktop.org/basedir-spec
- Midnight Commander documentation:
/opt/homebrew/share/doc/mc/orman mc
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
sudowas used extensively for home directory operations
Warning signs indicating you need this:
1# Multiple apps cannot write to home directory2touch ~/test.txt3# Permission denied4
5# Even new files show wrong ownership6ls -l ~/test.txt7# -rw-r--r-- 1 root staff 0 Feb 1 10:30 test.txtSIP (System Integrity Protection) Considerations
If the command fails with "Operation not permitted," SIP may be blocking it. Check SIP status:
1csrutil status2# System Integrity Protection status: enabled.To run diskutil resetUserPermissions with SIP enabled:
- Reboot into Recovery Mode (hold Cmd+R on Intel, hold Power on Apple Silicon)
- Open Terminal from Utilities menu
- Mount your volume (if not auto-mounted):
bash1diskutil list2diskutil mount disk1s1 # adjust disk identifier
- Run the reset:
bash1diskutil resetUserPermissions /Volumes/Macintosh\ HD $(dscl /Volumes/Macintosh\ HD/var/db/dslocal/nodes/Default -read /Users/username UniqueID | awk '{print $2}')
- 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:
1which mc2# Should output: /opt/homebrew/bin/mc (Apple Silicon) or /usr/local/bin/mc (Intel)3
4# Check if mc can see its own info5mc --versionTroubleshooting Multiple Homebrew Installations
If you've migrated from Intel to Apple Silicon or have both installations:
1# List all mc binaries2find /usr/local /opt/homebrew -name mc -type f 2>/dev/null3
4# Check PATH precedence5echo $PATH | tr ':' '\n' | nl6
7# Force use of specific installation8/opt/homebrew/bin/mc # Apple Silicon9/usr/local/bin/mc # Intelb 1 10:30 .config10
11# Mixed ownership (parent OK, child broken)12drwxr-xr-x 5 username staff 160 Feb 1 10:30 .config13drwxr-xr-x 3 root wheel 96 Feb 1 10:31 .config/mcThe 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:
1ls -le ~/.local ~/.cache ~/.config2stat -f "%N uid=%u gid=%g mode=%Sp" ~/.local ~/.cache ~/.configIf you see unknown ACL entries, you can drop them (use cautiously):
1chmod -RN ~/.local ~/.cache ~/.configHomebrew health check
Ensure your Homebrew prefix and environment are consistent, and that mc is installed where you expect:
1brew doctor2brew --prefix midnight-commander3brew list --versions midnight-commanderLast-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+):
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:
1export MC_CONFIG_DIR="$HOME/.config/mc"2export MC_DATA_DIR="$HOME/.local/share/mc"3mc