skip to content

System Administration

Administering macOS from the terminal — diskutil, mdutil, networksetup, system_profiler, defaults for plist edits, and softwareupdate — plus MDM profiles once you manage a fleet. Relevant to developer-experience and IT-adjacent engineering roles.

on this pageshow

questions

6

On macOS, you edit an application's preferences .plist file in ~/Library/Preferences by hand while the app is running, and your change disappears. Why, and what is the supported way to set that preference?

level: middleimportance: must knowfreq 55%

answer

  1. a daemon owns the file, not you
  2. reads and writes are both cached
  3. the plist is a backing store
  4. cfprefsd flushes over your edit
  5. defaults write, then restart the consumer

basics

~20 s

The preferences daemon cfprefsd owns those files, caches each domain in memory, and flushes its own copy back to disk — overwriting a hand edit. Use the defaults command (or the CFPreferences API), which goes through cfprefsd, then restart the app that reads the setting.

solid answer

~50 s

macOS preferences are not plain config files you own; they are a **domain database** fronted by `cfprefsd`, the per-user and per-root preferences daemon. When a process reads or writes a preference through CFPreferences, `cfprefsd` serves it from an in-memory cache and lazily writes the domain back to `~/Library/Preferences/<domain>.plist`. Editing that file directly races the daemon: it may never notice your change, and when it next flushes it writes its cached copy over you. The supported path is `defaults write com.apple.dock autohide -bool true`, which talks to `cfprefsd` so the daemon's cache and the file agree. Two extras matter. Reading is also cached, so a running app usually needs a restart — `killall Dock` for the Dock — before it picks the value up. And sandboxed apps keep preferences under `~/Library/Containers/<bundle-id>/Data/Library/Preferences`, so the top-level path may not be the file being read at all.

code

bash · 11 lines
bash
# Read, write and verify through the daemon, then restart the consumer
defaults read com.apple.finder AppleShowAllFiles 2>/dev/null || echo "not set"
defaults write com.apple.finder AppleShowAllFiles -bool true
defaults read com.apple.finder AppleShowAllFiles
killall Finder

# Inspect a plist that is stored in binary form, without modifying it
plutil -convert xml1 -o - ~/Library/Preferences/com.apple.finder.plist | head -20

# Check whether a profile is managing the same domain
ls /Library/Managed\ Preferences/

go deeper

for a junior

Be ready to say that macOS preferences are changed with the defaults command, and that the app usually has to be restarted before the new value shows up.

for a middle

Explain the mechanism: cfprefsd mediates the domain, caches it in memory, and can flush its cache over a hand-edited file, which is why the supported interface is the API rather than the file.

for a senior

Demonstrate the debugging path for a preference that will not stick — managed preferences from a profile shadowing the user domain, sandbox containers, ByHost settings, and when restarting the daemon is justified.

for a principal

Own the fleet question: settings that must be enforced belong in a configuration profile as managed preferences, not in login scripts running defaults write, because scripted user-domain writes are advisory and drift the moment a user changes them back.

## Preferences are a database, not a file On Linux you edit a config file and the daemon rereads it. macOS does not work that way. A preference lives in a **domain** — usually a reverse-DNS bundle identifier like `com.apple.dock` — and the domain is mediated by `cfprefsd`, a daemon that runs once per user session and once as root. Applications call the CFPreferences / `NSUserDefaults` APIs; those APIs talk to `cfprefsd` over XPC; `cfprefsd` maintains the in-memory state and decides when to persist it to a property-list file. The `.plist` file under `~/Library/Preferences` is therefore the daemon's **backing store**, not the interface. Treating it as the interface produces exactly the symptom in the question: you write valid XML, the daemon has never been told, and the next flush of its cached domain replaces the file wholesale. There is a second, dumber trap in the same directory: modern preference files are usually **binary property lists**, not XML. A text editor either refuses them or corrupts them. `plutil -convert xml1 -o - file.plist` prints a readable version, and `plutil -lint` validates one, but converting the on-disk file still does not tell `cfprefsd` anything. ## The supported interface `defaults` is a thin command-line client of the same API the apps use: ```bash defaults read com.apple.dock autohide defaults write com.apple.dock autohide -bool true defaults delete com.apple.dock autohide defaults domains # every domain in the user's search list ``` Because it goes through `cfprefsd`, the daemon's cache and the file stay consistent. Types are explicit — `-bool`, `-int`, `-float`, `-string`, `-array`, `-dict`, `-data` — and getting the type wrong is a real failure: an app reading a boolean will not accept the string `"true"`. Nested values are reachable with `defaults write <domain> <key> -dict-add <subkey> <value>`. A `defaults write` affects the *current* user's domain. Running it under `sudo` writes root's preferences, which is almost never what a support script intended; to set a preference for another user you run `defaults` as that user, and to set a machine-wide default you write a domain under `/Library/Preferences`. ## Why the app still shows the old value Reads are cached too. A running application asked `cfprefsd` for the domain once, got the values, and holds them. Setting the preference underneath it changes nothing visible until the app rereads. That is why every macOS tweak recipe ends with a restart of the consumer: ```bash defaults write com.apple.finder AppleShowAllFiles -bool true killall Finder ``` When even `defaults read` seems to return stale data — which happens if something *did* edit the file behind the daemon's back — `killall cfprefsd` forces the daemon to restart and reload from disk. It is a recovery step, not a normal part of setting a preference. ## The two other locations that catch people out **Sandboxed applications** (anything from the App Store, and many others) do not use `~/Library/Preferences/<domain>.plist`. Their preferences live inside their container at `~/Library/Containers/<bundle-id>/Data/Library/Preferences/<domain>.plist`. Confusingly, `defaults write com.example.app key value` still usually works, because the sandbox redirects the domain — but a script that hunts for the file path will be looking in the wrong place. **Per-host preferences** — settings that should not follow a user to another machine — live in `~/Library/Preferences/ByHost/` and are addressed with `defaults -currentHost read <domain>`. Reading the plain domain for a ByHost setting returns nothing, which looks like the setting does not exist. ## Managed preferences win On a managed Mac there is a fourth layer: preferences delivered by a configuration profile land in `/Library/Managed Preferences/` and take precedence in the CFPreferences search order. A user-level `defaults write` for the same key appears to succeed and then has no effect, because the managed value shadows it. When a preference "will not stick" on a corporate laptop, checking for a managed domain is the fast diagnosis. ## The shape of a good answer Say that preferences are daemon-mediated, name `cfprefsd`, explain that direct file edits race its cache, give `defaults` as the interface plus the consumer restart, and mention at least one of the location traps — sandbox containers, ByHost, or managed preferences. That sequence shows you have actually debugged a preference that would not stick rather than copied a one-liner from a blog.

  • You run defaults write for a setting on a corporate laptop, it reports no error, and the setting does not change. What do you check?
    Whether the domain is managed. Configuration-profile-delivered preferences land in `/Library/Managed Preferences/` and outrank the user domain in the CFPreferences search order, so your write lands but is shadowed. Check for the domain there and look at the installed profiles. If it is not managed, check whether the app is sandboxed (its real store is inside `~/Library/Containers/`), whether the setting is per-host, and whether the consumer simply needs restarting.
  • When is killall cfprefsd appropriate, and why is it not part of a normal preference change?
    It is a recovery step for when the daemon's cache and the on-disk file have diverged — usually because something wrote the plist directly. Restarting the daemon makes it reload from disk. In a normal change you never need it: `defaults write` goes through the daemon, so cache and file already agree, and the only thing left is restarting the app that reads the value.
  • Why does the type flag on defaults write matter?
    Because the property list stores typed values and the reading app expects a specific type. `defaults write com.example.app enabled true` stores the string `"true"`, which a boolean read will not interpret as true; `-bool true` stores a real boolean. The same applies to `-int` versus a numeric string. Type mismatches are a frequent cause of a written preference that the app silently ignores.

saying these in an interview costs you the question

  • Treating ~/Library/Preferences plists as ordinary editable config files
  • Thinking a preference change takes effect without restarting the reader
  • Running defaults write under sudo to change a user's setting
  • Assuming every app's plist sits at the top-level Preferences path
  • Editing a binary plist in a text editor and corrupting it

context

open as a page

On a Mac you have only shell access to, how do you determine the macOS version and whether the hardware is Apple Silicon or Intel — and what can make each of those checks report the wrong thing?

level: juniorimportance: should knowfreq 58%

basics

~20 s

Use sw_vers for the macOS product version and build, uname -m for the CPU architecture (arm64 on Apple Silicon, x86_64 on Intel), and system_profiler SPHardwareDataType for model, chip and serial number. Rosetta translation can make uname -m report x86_64 on an Apple Silicon machine.

open as a page

A colleague adds a nameserver line to /etc/resolv.conf on a Mac and reports that DNS resolution is unchanged for their apps. Why does that happen on macOS, and how do you actually change and inspect the system's DNS configuration?

level: middleimportance: should knowfreq 42%

basics

~20 s

On macOS /etc/resolv.conf is generated from the SystemConfiguration store, not read as the source of truth; the system resolver goes through mDNSResponder using per-interface settings. Change DNS with networksetup -setdnsservers (or the network settings UI) and inspect the real configuration with scutil --dns.

open as a page

On a managed Mac fleet, what is a configuration profile, and what can an MDM enforce through one that a shell script running as root on the same machine cannot?

level: seniorimportance: should knowfreq 46%

basics

~20 s

A configuration profile is a signed property-list document of typed payloads that macOS installs as managed policy. Since macOS 11 profiles cannot be installed from the command line — only by user approval or by an MDM — and some settings, notably privacy approvals and extension allowlists, are only honoured from a supervised, MDM-managed Mac.

open as a page

A macOS build machine shows mds_stores consuming CPU and hammering the disk whenever a build runs. What is that process doing, and how do you control it for specific volumes or directories?

level: middleimportance: nice to knowfreq 26%

basics

~20 s

That is Spotlight's metadata indexer reacting to the thousands of files a build creates and deletes. Use mdutil to check status and disable indexing per volume (mdutil -i off), and keep individual directories out of the index by naming them with a .noindex suffix or adding them to the Spotlight privacy list.

open as a page

You need to apply macOS updates across a fleet of Macs without a person at each keyboard. What does the softwareupdate command let you do, and why do Apple Silicon machines make fully unattended OS updates harder?

level: seniorimportance: nice to knowfreq 33%

basics

~20 s

softwareupdate lists, downloads and installs updates from the command line and can fetch a full macOS installer. On Apple Silicon, installing a macOS update requires credentials of a volume owner, supplied with --user and --stdinpass or authorised centrally by an MDM-escrowed bootstrap token, so a plain root script is not enough.

open as a page