
You bought a Mac Mini. You set it up. You opened Terminal, ran ls, and got a wall of monochrome text. You typed ll and got command not found. You ran sudo something and — three commands later — had to type your password again. Sound familiar?
This guide fixes all four problems with copy-paste commands, a one-shot script, and a 15-minute payoff. Every fact here is verified against the official sudoers(5) manual page, Apple's macOS Catalina announcement, and the BSD ls documentation. No magic, no guesswork.
Out of the box, your Mac Mini inherits four mildly infuriating terminal defaults:
| Issue | Default | Pain Level |
|---|---|---|
sudo re-auth window |
5 minutes (per sudoers(5) man page) | 😤 Type password 10×/day |
ll command |
Doesn't exist | 😐 Linux muscle memory breaks |
Colored ls |
Off by default | 😑 Hard to spot directories |
| Default shell | /bin/zsh on new accounts (since Catalina 2019), but /bin/sh on root by default |
🤔 Inconsistent behavior |
Let's kill them all.
sudo Timeout to 8 HoursThe default 5-minute timeout is hardcoded into the sudoers policy plugin. The official sudoers(5) manual page is explicit:
"The user may then use sudo without a password for a short period of time (5 minutes unless overridden by the
timestamp_timeoutoption)."
To override it, you don't edit the main /etc/sudoers file — you drop a fragment in /etc/sudoers.d/. That's the modern, safer way.
# Make a sudoers.d fragment (file MUST be mode 0440 and owned by root)
sudo tee /private/etc/sudoers.d/terminal_tweaks >/dev/null <<'EOF'
Defaults timestamp_timeout=480
EOF
sudo chmod 0440 /private/etc/sudoers.d/terminal_tweaks
The value is in minutes, so 480 = 8 hours. Open a new terminal and sudo date repeatedly — your password is now cached for a full workday.
| Value | Behavior |
|---|---|
0 |
Ask every time (CIS Benchmark recommendation for shared Macs) |
5 |
Default |
30 |
Common laptop setting |
480 |
8 hours — our pick for solo home use |
-1 |
Never expire — don't do this on a portable Mac |
The MacPerformanceGuide confirms this is the standard pattern, and shows a real macOS /etc/sudoers example using timestamp_timeout=30.
ll Alias (and Friends)macOS doesn't ship with ll because Apple's default .zshrc is a 12-line stub. Linux distros preload ll in /etc/skel/.bashrc; Apple decided not to. Two minutes to fix:
# Add to ~/.zshrc
cat >> ~/.zshrc <<'EOF'
# >>> set-terminal-preference >>>
alias ll='ls -lhF' # long format, human sizes, type markers
alias la='ls -lhAF' # above + show hidden (skip . and ..)
alias lt='ls -lhAFt' # above + sort by mtime (newest first)
alias l='ls -CF' # compact columns
# <<< set-terminal-preference <<<
EOF
source ~/.zshrc
Now ll works in every new terminal, plus you've got la for "list all" and lt for "list by time" — both hugely useful when hunting for the file you just edited.

This is the part where macOS gets really confusing for Linux refugees. macOS uses BSD ls, not GNU ls, so the environment variable is LSCOLORS (no underscore between LS and COLORS), and it has a different syntax.
The LSCOLORS string is exactly 22 characters — 11 pairs of foreground/background. Lowercase = normal, uppercase = bold. The BigSoft LS_COLORS reference breaks it down cleanly:
| Pair # | What it colors |
|---|---|
| 1 | directory |
| 2 | symbolic link |
| 3 | socket |
| 4 | pipe |
| 5 | executable |
| 6 | block special |
| 7 | character special |
| 8 | setuid executable |
| 9 | setgid executable |
| 10 | dir writable by others, sticky bit |
| 11 | dir writable by others, no sticky bit |
Color codes: a=black b=red c=green d=brown e=blue f=magenta g=cyan h=light grey x=default background. UPPERCASE = bold/bright.
# Add to ~/.zshrc
export CLICOLOR=1
export LSCOLORS="ExGxBxDxCxEgEdxbxgxcxd"
That preset is the one Apple itself ships in its own support docs — bold blue directories, bold magenta symlinks, bold green executables, all readable on a dark background. Done.
ls via HomebrewIf you want per-extension coloring (Python files in green, archives in red, images in magenta, etc.), the BSD ls can't do that — but GNU ls can. Install via Homebrew:
brew install coreutils
# In ~/.zshrc:
eval "$(gdircolors -b)"
alias ls="gls --color=auto"
alias ll="gls -lhAF --color=auto"
You get the full Linux rainbow. The cost is a 50-line LS_COLORS string and a one-time Homebrew install. Worth it if you live in the terminal.

Apple made zsh the default shell in macOS Catalina (10.15, fall 2019) for new user accounts. The reason, as The Verge reported: Apple was stuck on bash 3.2 (from 2007) because newer bash is licensed under GPLv3, and Apple refuses to ship GPLv3 software. zsh is MIT-licensed.
For your user account, this is usually already done. For root, it isn't — dscl . -read /Users/root UserShell returns /bin/sh. That's why your carefully written /var/root/.zshrc was being ignored when you sudo -i'd in.
Fix it for both:
# 1. Make sure /bin/zsh is in the allowed shells list
grep -q '^/bin/zsh$' /etc/shells || echo "/bin/zsh" | sudo tee -a /etc/shells
# 2. Change your own shell
chsh -s /bin/zsh
# 3. Change root's shell (this is the bit most people miss)
sudo dscl . -change /Users/root UserShell /bin/sh /bin/zsh
Now both you and root drop into zsh on login, so your ~/.zshrc aliases and colors work everywhere — including sudo -i and SSH sessions.

set-terminal-preference.shSave the script below as set-terminal-preference.sh, then run it once with bash set-terminal-preference.sh. It's idempotent — safe to re-run, creates .bak files on first run, and uses a sudoers.d/ fragment so it never touches the main /etc/sudoers.
#!/bin/bash
# set-terminal-preference.sh
# One-shot macOS terminal setup: 8h sudo, ll alias, colors, zsh default.
# Run: bash set-terminal-preference.sh
set -euo pipefail
[[ "$(uname)" == "Darwin" ]] || { echo "macOS only"; exit 1; }
# 1) sudo timeout → 8 hours
SUDOERS_D="/private/etc/sudoers.d/terminal_tweaks"
sudo tee "$SUDOERS_D" >/dev/null <<'EOF'
Defaults timestamp_timeout=480
EOF
sudo chmod 0440 "$SUDOERS_D"
# 2) shell aliases + colors
for RC in "$HOME/.zshrc" "$HOME/.bashrc"; do
[[ -f "$RC" ]] || touch "$RC"
sed -i '' '/# >>> set-terminal-preference >>>/,/# <<< set-terminal-preference <<</d' "$RC"
cat >> "$RC" <<'EOF'
# >>> set-terminal-preference >>>
alias ll='ls -lhF'
alias la='ls -lhAF'
alias lt='ls -lhAFt'
alias l='ls -CF'
export CLICOLOR=1
export LSCOLORS="ExGxBxDxCxEgEdxbxgxcxd"
# <<< set-terminal-preference <<<
EOF
done
# 3) default shell → zsh (for current user + root)
grep -q '^/bin/zsh$' /etc/shells || echo "/bin/zsh" | sudo tee -a /etc/shells
chsh -s /bin/zsh
if [[ $EUID -eq 0 ]]; then
CUR=$(dscl . -read /Users/root UserShell | awk '{print $2}')
dscl . -change /Users/root UserShell "$CUR" /bin/zsh
fi
echo "✅ Done. Run: source ~/.zshrc"
Re-running it won't duplicate anything — it strips the previous block and re-adds a clean one.
timestamp_timeout=0 is the CIS Benchmark recommendation for shared Macs and corporate laptops. For your home Mac Mini that sits behind a locked door, 8 hours is fine. For a work MacBook, 30 minutes is the sweet spot.
Don't use timestamp_timeout=-1 ("never expire"). It feels great in development, but it means a stolen laptop with an unlocked screen = full root access forever. Not worth the convenience.
The /private/etc thing: /etc on macOS is actually a symlink to /private/etc. They look like two folders but they're one. If a tool insists on /private/etc/sudoers, that's why.
Verifying your work: After the script runs, open a new terminal and try:
ll # should list with human sizes + colors
sudo echo hi # should work without prompting (if 5 min hasn't passed)
echo $SHELL # should say /bin/zsh
sudo -i && echo $SHELL # should ALSO say /bin/zsh (root)
If all four checks pass, you're done. Welcome to a saner Mac.
timestamp_timeout override/etc/sudoers examplechsh syntax and /etc/shells listCLICOLOR vs LSCOLORS (BSD) vs LS_COLORS (GNU)