#!/bin/bash # Find the `defaults` key behind a setting you changed in System Settings, so it # can go in macos-defaults.sh instead of being remembered. # # macos-defaults-diff snapshot, wait while you change one setting, # then print what moved # macos-defaults-diff snap take the snapshot only # macos-defaults-diff show compare now against the last snapshot # # It reads both the global domains and the per-host ones (`-currentHost`), which # is where several trackpad, mouse and font settings live and which a plain # `defaults read` never shows. # # Change ONE setting at a time. macOS writes unrelated keys constantly -- window # positions, recent items, sidebar widths -- so a diff after three changes is # mostly noise with your key hidden in it. # # Quit System Settings before the second snapshot. It holds changes in memory # and cfprefsd may not have written them yet; the line below flushes that cache. # # Runs under macOS's /bin/bash 3.2. set -euo pipefail if [[ "$(uname)" != "Darwin" ]]; then >&2 echo "macos-defaults-diff: macOS only" exit 1 fi dir="${TMPDIR:-/tmp}/macos-defaults-diff" mkdir -p "${dir}" snapshot() { local tag="$1" # cfprefsd caches writes; without this a change made seconds ago can be # missing from the read that is supposed to reveal it. killall cfprefsd 2>/dev/null || true sleep 1 defaults read > "${dir}/${tag}.txt" 2>/dev/null || true defaults -currentHost read > "${dir}/${tag}-host.txt" 2>/dev/null || true } report() { if [[ ! -f "${dir}/before.txt" ]]; then >&2 echo "macos-defaults-diff: no snapshot yet -- run 'macos-defaults-diff snap' first" exit 1 fi snapshot after local found="" if ! diff -u "${dir}/before.txt" "${dir}/after.txt" > "${dir}/delta.txt" 2>&1; then found=y echo "=== global domains" grep -E '^[+-]' "${dir}/delta.txt" | grep -vE '^(\+\+\+|---)' | sed 's/^/ /' fi if ! diff -u "${dir}/before-host.txt" "${dir}/after-host.txt" > "${dir}/delta-host.txt" 2>&1; then found=y echo "=== this host only -- these need 'defaults -currentHost write'" grep -E '^[+-]' "${dir}/delta-host.txt" | grep -vE '^(\+\+\+|---)' | sed 's/^/ /' fi if [[ -z "${found}" ]]; then echo "nothing changed." echo "Some settings are not in defaults at all: anything behind Privacy &" echo "Security lives in the SIP-protected TCC database, and a few panes use" echo "private APIs. Those cannot be scripted -- note them in macos-defaults.sh" echo "as manual steps instead." return fi echo echo "The domain is the nearest heading above the changed line in:" echo " ${dir}/delta.txt" echo "Write it as: defaults write \"\" -bool/-int/-string " echo "then add it to macos-defaults.sh, and restart whatever owns it" echo "(killall Dock, killall Finder, or log out)." } case "${1:-}" in snap) snapshot before echo "snapshot taken. Change one setting, then: macos-defaults-diff show" ;; show) report ;; "") snapshot before echo "Snapshot taken. Now change ONE setting in System Settings, quit it," printf 'then press Enter: ' read -r _ report ;; -h|--help) sed -n '3,21p' "$0" | sed 's/^# \{0,1\}//' ;; *) >&2 echo "macos-defaults-diff: unknown argument: $1" exit 1 ;; esac