macOS
セキュリティ警告

macOS system administration, command-line differences from Linux, and automation best practices.

インストール
$clawhub install macos

BSD vs GNU Commands

  • sed -i requires extension argument: sed -i '' 's/a/b/' file — empty string for no backup, Linux doesn't need it

  • find doesn't support -printf — use -exec stat or xargs with stat -f instead

  • date uses different format flags: date -j -f '%Y-%m-%d' '2024-01-15' '+%s'-j prevents setting time

  • grep -P (Perl regex) doesn't exist — use grep -E (extended) or install ggrep via Homebrew

  • xargs defaults to /usr/bin/echo not the command — always specify the command explicitly

  • readlink -f doesn't exist — use realpath or python3 -c "import os; print(os.path.realpath('path'))"

Homebrew Paths

  • Apple Silicon: /opt/homebrew/bin, /opt/homebrew/lib

  • Intel: /usr/local/bin, /usr/local/lib

  • Check architecture: uname -m returns arm64 or x86_64

  • Homebrew doesn't add to PATH automatically — check ~/.zprofile for eval line

  • Running x86 binaries: arch -x86_64 /bin/bash then install/run Intel-only tools

Keychain (Secrets)

  • Store: security add-generic-password -a "$USER" -s "service_name" -w "secret_value" -U

  • Retrieve: security find-generic-password -a "$USER" -s "service_name" -w

  • -U flag updates if exists — without it, duplicate entries error

  • Keychain prompts for access on first use — authorize permanently for automation

  • Delete: security delete-generic-password -a "$USER" -s "service_name"

launchd (Services)

  • User agents: ~/Library/LaunchAgents/ — runs as user when logged in

  • System daemons: /Library/LaunchDaemons/ — runs at boot as root

  • Load: launchctl load -w ~/Library/LaunchAgents/com.example.plist

  • Unload before editing: launchctl unload — edits to loaded plists are ignored

  • Check errors: launchctl list | grep service_name then launchctl error <exit_code>

  • Logs: log show --predicate 'subsystem == "com.example"' --last 1h

Privacy Permissions (TCC)

  • Automation scripts fail silently without Full Disk Access or Automation permissions

  • Grant in System Settings → Privacy & Security → corresponding category

  • Terminal and iTerm need separate permissions — granting to one doesn't grant to other

  • tccutil reset clears permissions: tccutil reset AppleEvents for Automation

  • Check granted permissions: sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db "SELECT * FROM access"

defaults (Preferences)

  • Read: defaults read com.apple.finder AppleShowAllFiles

  • Write: defaults write com.apple.finder AppleShowAllFiles -bool true

  • Delete: defaults delete com.apple.finder AppleShowAllFiles

  • Restart app after changing: killall Finder

  • Find app bundle ID: osascript -e 'id of app "App Name"'

  • Export all: defaults export com.apple.finder - outputs XML

File Operations

  • ditto preserves resource forks and metadata — use instead of cp for app bundles

  • Create DMG: hdiutil create -volname "Name" -srcfolder ./folder -format UDZO output.dmg

  • Mount DMG: hdiutil attach image.dmg — returns mount point path

  • Unmount: hdiutil detach /Volumes/Name

  • Extended attributes: xattr -l file to list, xattr -c file to clear all

  • Quarantine removal: xattr -d com.apple.quarantine app.app

Clipboard

  • Copy to clipboard: echo "text" | pbcopy

  • Paste from clipboard: pbpaste

  • Copy file contents: pbcopy < file.txt

  • Preserve RTF: pbpaste -Prefer rtf

  • Clipboard works in SSH sessions to local machine — useful for remote file copying

Screenshots and Screen

  • Screenshot region to file: screencapture -i output.png

  • Screenshot window: screencapture -w output.png

  • Screenshot to clipboard: screencapture -c

  • Headless (no UI): screencapture -x — suppresses sound and cursor

  • Screen recording requires Screen Recording permission in Privacy settings

Process Management

  • Prevent sleep: caffeinate -i command — keeps system awake while command runs

  • Prevent sleep with timeout: caffeinate -t 3600 — 1 hour

  • Check why not sleeping: pmset -g assertions

  • Power settings: pmset -g to view, sudo pmset -a sleep 0 to disable sleep

  • Current app in focus: osascript -e 'tell application "System Events" to get name of first process whose frontmost is true'

Network

  • List interfaces: networksetup -listallhardwareports

  • Get IP: ipconfig getifaddr en0 (Wi-Fi usually en0 on laptops)

  • DNS servers: scutil --dns | grep nameserver

  • Flush DNS: sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder

  • Proxy settings: networksetup -getwebproxy "Wi-Fi"

System Integrity Protection

  • Check status: csrutil status

  • Disable (Recovery Mode only): csrutil disable — not recommended for production

  • Protected paths: /System, /usr (except /usr/local), /sbin, /bin

  • Can't modify these even as root — design your automations around this

Logs

  • Stream live: log stream --predicate 'process == "processname"'

  • Search recent: log show --last 1h --predicate 'eventMessage contains "error"'

  • Subsystem filter: log show --predicate 'subsystem == "com.apple.example"'

  • Save to file: log collect --output ./logs.logarchive — opens in Console.app

Automation Tips

  • Open URL: open "https://example.com" — uses default browser

  • Open app: open -a "Safari" — by name, not path

  • Open file with specific app: open -a "TextEdit" file.txt

  • Run AppleScript: osascript -e 'tell application "Finder" to get name of home'

  • Spotlight search: mdfind "kMDItemDisplayName == 'filename.txt'" — faster than find for indexed files