The best laptop money can buy:
https://www.apple.com/uk/macbook-pro/
If you don't have an M3 Pro / Max - you're missing out on an excellent (but overpriced) machine.
On balance of price vs performance the Macbook Air M3 is excellent, and even thinner and lighter than the Macbook Pro - a real joy to use. Even when you're using more RAM than the physical 16GB max and swapping, the performance is still so good you don't notice significant performance degradation for most usage, even when using heavyweight IDEs like IntelliJ.
- WARNING: Battery Life
- Terminal
- BioMetrics
- Homebrew - Package Management
- Mas - App Store Apps Management
- Activity Monitor
- Force Quit Applications
- Stats Bar
- Rearrange Status Bar Icons
- Menu Bar Managers
- Pingr
- Flux
- Blurred
- Reducing Desktop Workspaces
- Sending Control-Alt-Delete to Windows through Remote Desktop
- Virtualization
- Anti-Virus
- Raycast
- Alfred
- AppleScript
- Automator
- Commands
- Spotlight - Search for or Open anything
- Open URL from Terminal output
- Open
- Open URL in the default web browser
- Open current directory in Finder
- Open image in the default app (usually Preview)
- Show the File in Finder
- Open an Application from the command line
- Useful Open Switches
- Check default Application for a given file type
- Change the default Application for a given file type
- Clipboard
- System Information
- Screenshots
- Screen Recording
- Networking
- Say - text-to-speech
- Finding Files - Spotlight Search and Index Management
- Power Management
- Packages
- Launchctl
- Start At Login
- Notifications
- Disk Management
- Service Management
- Sound Management
- Shazam Songs while using Headphones
- Hammerspoon - System Event Handler
- KeyChain Access
- Binaries Debugging
- Creating Bootable CDs & USBs from ISOs
- Asahi Linux on Apple Silicon
- XCode Mobile App Builds
- Time Machine
- External Disk Management
- Troubleshooting
- Wifi Capture Portal Not Loading
- Another Device Using Your IP
- DNS Servers Not Respected
- Discrepancy Between
dfanddu - Spotlight Search failing to find App
- XCodeBuild error complaining XCode only has command line tools
- Application Fails to Open
- Cannot Delete - No Space Left on Device
- Emergency Backup
- Bootup Hangs on Black Screen after Full Data Disk
- Emergency File Backup from Recovery Mode
- Reinstall macOS & Restore Data
- Relevant GitHub Repos
- Memes
Ensure it is on a table and not heat capturing linen like you bed, especially if travelling.
Within a few weeks of digitial nomadding working on beds with my laptop on the bed cover, I had degraded the battery of my new Macbook Pro M3 Max to 85%, and even after being more careful, after a year it was down to 79%.
This screenshot from Stats Bar shows why - it's using only Efficiency Cores rather than Performance Cores:
This is where you should be spending your life if you're a techie, with a browser to supplement referencing documentation.
$COLUMNS- 179 column width on my MacBook Pro 13" terminal
- 204 on my MacBook Pro Retina 15" terminal
- 215 on my Macbook Pro M3 2023 terminal - resolution gets better over time
On newer Macs, ensure your have fingerprint login set up.
Check current biometric settings:
bioutil -rEnable biometrics:
sudo bioutil -w -s -u 1Add your fingerprints in the GUI (this can't be done from the command line):
Apple menu → System Settings → Touch ID & Password → Add Fingerprint
The best most widely used package manager for Mac.
See the Homebrew.md page for how to use it and great package lists I've spent years discovering and building up.
Command line interface to the macOS App Store.
See the Mas page for how to install and use it.
See your CPU, RAM, Disk, Network and Energy usage of applications.
Sorting by CPU and RAM descending on their tabs is usually your first port of call.
To open Activity Monitor you can type Cmd-Space to open Spotlight search bar and the start typing Activity Monitor
to find it and hit enter to open it.
On the command line you can also just run this:
open -a "Activity Monitor"You can use Activity Monitor above or bring up the Force Quit Applications dialogue box using this key combo:
Cmd + Option + Esc
Stats gives many nice toolbar stats on your Mac's performance for:
- CPU
- GPU
- RAM
- Disk
- Network
- Battery
brew install statsopen -a "Stats"Battery even tells you:
- time to discharge
- time to charge
- number of charge cycles
- battery health %
- remaining charge / capacity in mAh (the capacity decreases as the battery health degrades - this is very useful to see)
- which apps which are consuming a lot of energy for you to kill them if you're not needing them, helping your battery life when on the move
Start Stats.app at login - configure this in its settings or run this command to do it automatically:
osascript -e 'tell application "System Events" to make login item at end with properties {path:"/Applications/Stats.app", hidden:false}'Now 14" Macbook Pros are powerful enough, but the screen space is very limited and you lose the top middle for the camera you end up losing icons behind the camera portion of the screen.
Rearrange your icons to put the most important and frequently used icons to the left while leaving icons you rarely click on like Google Drive to the left to be pushed underneath the camera.
To rearrange icons:
Cmd + Click + drag each icon to where you want it
Free menu bar managers because a 14" Macbook Pro has nowhere near enough space for all the icons I have.
All 3 free options I tried ( Ice, Vanilla, iBar ) require Accessibility and Screen Recording Permission to work properly, unfortunately.
Ice is the best of the 3, so I only cover that one here.
brew install jordanbaird-iceopen -a IceStart at login:
osascript -e 'tell application "System Events" to make login item at end with properties {path:"/Applications/Ice.app", hidden:false}'Another useful menu app for constant wifi network monitoring for those unreliable hotel wifis:
Better than leaving a ping running in a terminal.
This isn't available in Homebrew unfortunately as of time of writing so you actually have to click through and install it manually and then click the menu bar drop down to have it start automatically at login.
The Stats bar's network tool gives far more detailed info such as connectivity history graph, latency, bandwith usage and per app network breakdowns. I like the green dot item, but for the graph directly in menu bar, this app is nice.
Flux dims your display to remove blue light that keeps you awake.
brew install --cask flux-appStart Flux:
open -a FluxDims background windows - seems to not work consistently though.
I don't use this any more, not worth the CPU cycles IMO.
If you want to try it:
brew install blurredStart Blurred:
open -a BlurredStart at login:
osascript -e 'tell application "System Events" to make login item at end with properties {path:"/Applications/Blurred.app", hidden:false}'If like me, you hate the time lost in graphics sliding effect from one desktop workspace to another, especially caused
by apps like Windows Virtual Desktop in Remote Desktop opening to full screen, and just prefer good old fashioned
Cmd-Tab, then you can remove the extra workspaces as
described here
by pressing F3 and then hovering on and clicking the X to delete the extra workspaces.
Unfortunately, Remote Desktop still seems to slide and send to fullscreen in another temporary desktop workspace.
Fn + Control + Option + Delete
If you need to run some Windows or Linux on your Mac.
Use UTM as a user friendly frontend to Qemu virtualization on Apple Silicon chips.
Use Virtualbox if you're still on older x86_64.
You can also use Multipass.
See Virtualization page.
macOS has some built-in malware protection via XProtect;
https://support.apple.com/en-ae/guide/security/sec469d47bd8/web
Free Anti-Virus for Mac:
- Avast - easy click install, follow instructions to grant permissions
- AVG Free - similar to above, can only install one of AVG or Avast as they conflict and are owned by the same company
- Avira - easy click install, follow instructions to grant permissions then run a deep scan
- ClamAV - free open-source command line anti-virus
- ClamXAV - proprietary, developed by another company on top of ClamAV, with an added GUI and scheduling, more user friendly
https://docs.clamav.net/manual/Installing.html
brew install clamavDescription of components:
https://docs.clamav.net/manual/Usage.html
cd /opt/homebrew/etc/clamav/If DevOps-Bash-tools is cloned to $HOME/github,
link to its config, otherwise download it from GitHub.com:
for x in freshclam.conf clamd.conf; do
if test -f ~/github/bash-tools/configs/"$x"; then
ln -sv ~/github/bash-tools/configs/"$x" .
else
wget -nc "https://raw.githubusercontent.com/HariSekhon/DevOps-Bash-tools/refs/heads/master/configs/$x"
fi
doneVerify configs:
clamconfStart a manual freshclam foreground run to download the anti-virus signatures:
freshclamIf this succeeds, start freshclam as a background service:
freshclam -dStart the background ClamAV daemon:
sudo brew services start clamavThe daemon is owned by root, so is its socket,
so you need to sudo calls to access its socket for clamd to receive commands:
sudo clamdscan "$file"Monitor ClamD instances resource usage, jobs queued and signature databases loaded in an ncurses style interactive terminal output
sudo clamdtopPress q to quit / exit.
Standalone scanning without going through clamd:
clamscan "$file"clamscan .clamscan --recursive .Shortcut to everything.
Use as a drop in replacement for Spotlight which is full of garbage results like web pages in recent versions of Mac.
macOS power users often switch to Raycast or Alfred to use as app launchers as they are more predictable and respect local app priority rather than Spotlight which has been ruined trying to be a universal search usually resulting in poor results not giving you the local app you want to launch.
See Raycast page for installation and usage instructions as well as some useful extensions.
More mature app launcher replacement for Spotlight.
More configurable and extensible than Raycast.
The search bar looks simpler than Raycast, but has more options under the hood with workflows and powerpacks.
Install Alfred:
brew install --cask alfredStart Alfred in the background:
open -a "Alfred 5"or in case the version number changes:
open -a "$(echo /Applications/Alfred\ *.app)"Launch Alfred search bar:
Option + Space
Applescript sucks by comparison to Bash, and the debugging is even worse - from a trivial 10-20 line script you can get an error like this:
/get_application_names.scpt:882:889: script error: Expected “from”, etc. but found identifier. (-2741)
Line number 882:889 in a 20 line script?? Good luck finding the offending line.
Now imagine that was a 100 or 1000 line script.
Debugging Hell.
Still, there are some macOS UI related things for which this is the native code, see some such scripts under
the applescript/ directory in my DevOps-Bash-tools repo which
has many more Bash scripts that work on macOS and a bit of Python with the Quartz library for macOS:
Mac's Automator is awesome - it allows you to generate MacOS apps that look and work like real Mac applications using a custom workflow that can execute many native mac or external actions including running shell scripts.
You can create an Automator app that you can drag any file onto in Finder to have it execute any program such as a shell script with that file as the first argument.
Open Automator:
open -a AutomatorIf Automator prompts a small Finder window - click the New Document button.
If Automator is already running and you want to create a new one, click the top menu File -> New.
- Choose
Applicationfor your document type - Drag
Run Shell Scriptfrom the list of actions to the right hand pane - On the top right of the shell script box that appears on the canvass,
change the drop down for
Pass Inputtoas arguments - Paste the following script into the code box:
for file in "$@"; do
/path/to/your/script.sh "$file"
doneThe script will not inherit all your fancy .bashrc environment so ensure
that \$PATH to tools and environment variables are set or sourced in the script itself for portability.
- Save this as some
<name>.appand you will then be able to drag any file onto it in Finder to have it execute
A list of commands is provided at https://ss64.com/mac/.
Cmd-Space - opens Spotlight search (or preferably Raycast if you followed the section above) to
auto-complete and open anything quickly.
If this doesn't find an app which you know is there such as typing Spotify only returns Google Chrome or other wrong
results despite confirming that /Applications/Spotify.app exists, then see
Spotlight Search failing to find App in the Troubleshooting section.
Cmd + Click on the URL.
Open a file, folder, URL or Application.
open https://google.comopen .open file.jpgYou can also drag to the Terminal to paste a file or directory's path, or right-click copy and paste into the terminal to get its path on your command line.
If you have a big directory listing, sometimes it's easier to just
open -R "$file"This will open Finder with the file highlighted.
Use the name as seen under /Applications/ without the .app extension which is optional:
open -a "Google Chrome"open -a "SQLDeveloper"open -a "DBeaver"| Switch | Description |
|---|---|
-a APP |
Select which app to use to open it eg -a 'Google Chrome' |
-e |
Edit the file in TextEdit |
-g / --background |
Opens the application in the background |
-n / --new |
Open a new instance of the application even if one is already running |
-j / --hide |
Launches the app hidden |
-u / --url URL |
Open this URL, even if it exactly matches a filepath which would otherwise be preferred first |
--args |
All remaining arguments are passed in argv to the application's main() function instead of opened |
-R / --reveal |
Selects the file in the Finder instead of opening it |
-W / --wait-apps |
Blocks until the used applications are closed (even if they were already running) |
--env NAME=VALUE |
Adds an environment variable to be used by the application |
Install the duti app:
brew install dutiUse duti to check the default application for a given file type (eg .avi or .svg):
duti -x aviduti -x svgCheck the ID of the app you want to set it to:
osascript -e 'id of app "VLC"'output:
org.videolan.vlcChange all .avi files to be opened by VLC instead of the default QuickTime Player which will fail to open them:
duti -s org.videolan.vlc avi allChange all .svgfiles to be opened by Google Chrome which is much faster for viewing than whatever heavyweight image
editing application it is already set to (eg. Gimp or Inkscape):
duti -s com.google.Chrome public.svg-image allFirst find the ID of your favourite GUI Editor or IDE:
osascript -e 'id of app "IntelliJ IDEA CE"'outputs:
com.jetbrains.intellij.ce
The name of your IntelliJ app may be different depending on your version, you can use this one liner to find it:
printf '%s\n' /Applications/IntelliJ*.app | sed 's|.*/||; s/\.app$//'Then set the ID to be the default application for .sh extension files (instead of the Xcode.app editor which is the
standard default):
duti -s com.jetbrains.intellij.ce sh allCopy from stdin to clipboard:
pbcopy < input.txtPaste from clipboard to stdout:
pbpaste > output.txtYou may want to put the next couple of commands in initial debug steps for your Mobile iOS builds:
Model:
sysctl -n machdep.cpu.brand_stringApple M3 Max
Specs Summary:
system_profiler SPHardwareDataTypeHardware:
Hardware Overview:
Model Name: MacBook Pro
Model Identifier: Mac15,8
Model Number: Z1AU001K1B/A
Chip: Apple M3 Max
Total Number of Cores: 16 (12 performance and 4 efficiency)
Memory: 128 GB
System Firmware Version: nnnnn.nn.nn
OS Loader Version: nnnnn.nn.nn
Serial Number (system): xxxxxxxxxx
Hardware UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Provisioning UDID: xxxxxxxx-xxxxxxxxxxxxxxxx
Activation Lock Status: Enabled
RAM:
system_profiler SPMemoryDataTypeDisk Info:
diskutil listsystem_profiler SPStorageDataTypeUSB Info (for external USD backup disks):
system_profiler SPUSBDataTypeGraphics card:
system_profiler SPDisplaysDataTypeNetwork info:
system_profiler SPNetworkDataTypeSet screenshots to go to a dedicated folder:
defaults write com.apple.screencapture location -string ~/Desktop/ScreenshotsThis is cleaner than having them all over your Desktop background and easier to search for them
(hint: organize the ~/Desktop/Screenshots folder by date).
Pre-create the directory:
mkdir -v ~/Desktop/ScreenshotsSet the Screenshots directory as a list view
osascript -e '
tell application "Finder"
activate
open POSIX file "'"$HOME/Desktop/Screenshots"'"
delay 1
set the windowRef to Finder window 1
set current view of the windowRef to list view
end tell'Then click the Date Modified column header at the top to make your recent screenshots come to the top to be easy to
find.
(can't find a command line way to set the folder to sort by date. Add here if you know how)
Drag the Screenshots directory to the left-hand Favourites panel for quick easy access in future.
Cmd + Shift + 3
Cmd + Shift + 5
Ensure Capture Selected Window is selected in the screenshot bar that appears and then click on the application
window.
This is cleaner than dragging a rectangle which may catch some other cruft captured at mac's rounded corner application windows.
Switch mouse pointer to a cross-hair:
Cmd + Shift + 4
Then press down and drag a rectangular selection, release to screenshot it.
(press Esc to abort the press down without capturing if you need to start again)
A slightly more precious method is to use the screenshot bar:
Cmd + Shift + 5
Ensure Capture Selected Portion is selected in the screenshot bar and drag the edges of the rectangle until satisfied,
and then click the Capture button on the right of the screenshot bar.
The Screenshot.app in the Utilities folder is easy to use.
You can open it with the key combination:
Cmd + Shift + 5
or this command:
open /System/Applications/Utilities/Screenshot.appor
open -a ScreenshotMore details on Mac's native Screen Capture tool is here.
You may be prompted to allow Terminal to record the screen under Privacy & Security -> Screen Recording the first
time - it'll tell you that you have to restart the Terminal, but it worked for me without a restart.
Switches to select window to capture:
screencapture -W /tmp/screenshot.pngInteractive mode with full toolbar, same as the Screenshot.app:
screencapture -i -U /tmp/screenshot.pngVideo recording mode for 10 seconds (without -V it will record until you Ctrl-c it):
screencapture -v -V 10 /tmp/videocapture.mp4So many great options from delayed screenshots, copy to clipboard, open in Preview, capture a coordinate rectangle (great for automation!), see:
screencapture --helpOpen the Screenshot.app using key combination:
Cmd + Shift + 5
or this command:
open /System/Applications/Utilities/Screenshot.appor
open -a ScreenshotClick Record Entire Screen or Record Selected Portion.
This will create a .mov file in your screenshots directory (~/Desktop by default unless you've
Set Screenshot Location).
Share this with tech support without breaking your email storage capacity by using a file upload site such as https://0x0.st.
More details on Mac's native Screen Capture tool is here.
Alternatively you can do this from the command line using the screencapture command
as shown in The ScreenCapture CLI section above.
Another alternative is to use the QuickTime app, which gives you the same rectangle selection for video recording as the Screenshot app does.
Start the QuickTime player:
open -a "QuickTime Player.app"And then select File -> New Screen Recording or use shortcut Control + Command +N.
sudo ipconfig set en0 DHCPsudo ipconfig set en0 MANUAL 192.168.1.2 255.255.255.0netstat -rn | grep defaultExample output:
default 192.168.1.1 UGScg en0
sudo route add default 192.168.1.1scutil --dnsSometimes you want to use public DNS servers for better performance than the local DHCP given ones.
First you need to find the interface name, you cannot use the en0 type notation.
Find the network interfaces:
networksetup -listallnetworkservicesThe assign the IP addresses of the DNS servers to one of those named network interfaces, such as the Wi-Fi network interface:
sudo networksetup -setdnsservers Wi-Fi 4.2.2.1 4.2.2.2To set back to DHCP DNS servers, just clear the list:
sudo networksetup -setdnsservers Wi-Fi "Empty"In DevOps-Bash-tools the shell has a function dhcpdns to do this for all network
interfaces and remove the DNS search domains since you should inherit them from DHCP and not leak those FQDN
searches to the internet if on public networks.
sudo networksetup -setsearchdomains Wi-Fi mydomain.comIn DevOps-Bash-tools the shell has a function set_dns to do this for all network interfaces to
make this easier.
You should see these search domains appear in the class unix file /etc/resolv.conf managed by apple networking.
To remove DNS search domains:
sudo networksetup -setsearchdomains Wi-Fi "Empty"or clear_dns_search function in DevOps-Bash-tools to do this for all interfaces.
hostname=whitestarsudo hostname "$hostname"
sudo scutil --set HostName "$hostname"
sudo scutil --set ComputerName "$hostname"
sudo scutil --set LocalHostName "$hostname"scutil --get HostName
scutil --get ComputerName
scutil --get LocalHostNamedscacheutil -flushcache
sudo killall -HUP mDNSResponderBuilt-in available in macOS Monterey or later:
networkquality==== SUMMARY ====
Uplink capacity: 68.173 Mbps
Downlink capacity: 77.023 Mbps
Responsiveness: Low (322.581 milliseconds | 186 RPM)
Idle Latency: 204.167 milliseconds | 294 RPM
networksetup -getairportnetwork en0 | awk -F': ' '{print $2}'Prompts with a UI pop-up for administrative access to the system's keychain (sudo doesn't prevent this unfortunately):
security find-generic-password -g -w -D "AirPort network password" \
-a "$(networksetup -getairportnetwork en0 |
awk -F': ' '{print $2}')"networksetup -listpreferredwirelessnetworks en0 |
sed '/Preferred networks on/d;
s/^[[:space:]]*//' |
sort -fMake your Mac speak.
I used this to impress my kids, or even send a message from my loft study to my living room computer
by running say over an SSH login to the computer downstairs for them to hear!
say "Daddy is the greatest"You can also pipe in text:
echo "Daddy is the greatest" | sayTry different voices, list them like this:
say -v ?Speak from a text file and save it to an audio file:
say -f words.txt -o myaudioclip.aiffThe equivalent of locate on Linux, uses the Spotlight index:
mdfind [-onlyin /path/to/directory] [-name "$filename"] "$term"Check an app like Whatsapp is in the Spotlight index:
app=WhatsApp
mdfind "kMDItemKind == 'Application' && kMDItemFSName == '$app.app'"Erase and rebuild the Spotlight index:
mdutil -EDisable Spotlight indexing:
mdutil -a -i offEnable Spotlight indexing:
mdutil -a -i onCheck indexing status:
mdutil -s /Check indexing status for a specific folder (perhaps after disabling indexing on large or sensitive folders):
mdutil -s ~/Downloadspmset -gSystem-wide power settings:
Currently in use:
standby 1
Sleep On Power Button 1
hibernatefile /var/vm/sleepimage
powernap 1
networkoversleep 0
disksleep 10
sleep 0 (sleep prevented by coreaudiod, coreaudiod, sharingd, powerd)
hibernatemode 3
ttyskeepawake 1
displaysleep 180
tcpkeepalive 1
powermode 0
womp 1
pmset -g psNow drawing from 'AC Power'
-InternalBattery-0 (id=nnnnnnnn) 86%; charging; 0:35 remaining present: true
Only on Macbook / Macbook Pro:
pmset -g acOutput depends on whether you're plugged into AC power or not:
No adapter attached.
or
Wattage = 94W
Current = 4690mA
Voltage = 20000mV
AdapterID = nnnnn
Manufacturer = Apple Inc.
Family Code = 0xe000400a
Serial String = xxxxxxxxxxxxxxxxx
Adapter Name = 96W USB-C Power Adapter
Hardware Version = 1.0
Firmware Version = 01090057
Put the machine to sleep immediately using this command:
sudo pmset sleepnowsudo caffeinate -iPrevent sleep, but only if on AC power:
sudo caffeinate -sPackages installed via native .pkg installers.
sudo installer -pkg ~/Downloads/"$name".pkg -target /
To avoid pop-ups for things like CI/CD:
installer -showChoicesXML -pkg "$name".pkg |
tee choices.xmlThis is a plist xml file. Edit it:
"$EDITOR" choices.xmlThen re-run the installer with it:
sudo installer -applyChoiceChangesXML choices.xml -pkg "$name".pkgpkgutil --expand ~/Downloads/"$name".pkg /tmp/pkg_contentsThen just browse the /tmp/package_contents/... which may look similar to this:
tree /tmp/pkg_contents/tmp/pkg_contents
├── Distribution
├── Resources
│ ├── ixguard-white.png
│ └── ixguard.png
└── ixguard.pkg
├── Bom
├── PackageInfo
├── Payload
└── Scripts
├── postinstall
└── preinstall
4 directories, 8 files
List all .pkg installations:
pkgutil --pkgs | sortThis will be a long list of inverse domains for each package, such as:
com.amazon.aws.cli2
...
com.apple.pkg.CLTools_Executables
com.apple.pkg.CLTools_SDK_macOS13
com.apple.pkg.CLTools_SDK_macOS14
com.apple.pkg.CLTools_SwiftBackDeploy
com.apple.pkg.CLTools_macOS_SDK
...
com.apple.pkg.Xcode
...
com.google.drivefs.arm64
com.google.drivefs.shortcuts
...
com.guardsquare.ixguard
...
com.internet.wifispeed.speedtest
com.keepersecurity.commander.binary
com.keepersecurity.commander.launcher
...
com.microsoft.powershell
com.microsoft.rdc.macos
com.microsoft.teams
com.microsoft.teams2
com.ookla.speedtest-macos
com.openspeedtest.server
com.paloaltonetworks.globalprotect.pkg
...
com.vagrant.vagrant
...
net.whatsapp.WhatsApp
org.openvpn.client.pkg
org.openvpn.client_framework.pkg
org.openvpn.client_launch.pkg
org.openvpn.client_uninstall.pkg
org.openvpn.helper_framework.pkg
org.openvpn.helper_launch.pkg
ru.keepcoder.Telegram
us.zoom.pkg.videomeeting
This accesses launchd, Mac's init script equivalent.
See which launchd scripts are loaded:
launchctl listStop and unload script, add -w to remove it from the boot sequence:
sudo launchctl unload [path/to/script]Launch scripts are found in the following locations:
~/Library/LaunchAgents
/Library/LaunchAgents
/Library/LaunchDaemons
/System/Library/LaunchAgents
/System/Library/LaunchDaemons
Blog post on cool things launchd can do, like watching and executing on files that are dropped into directories.
See which apps are configured to start at login:
osascript -e 'tell application "System Events" to get the name of every login item'You should see a selection of apps:
Google Drive, ProtonVPN, WhatsApp, Stats, Terminal, SanDiskSecurityHelper, Flux, Hammerspoon
Add an app to start at login:
osascript -e 'tell application "System Events" to make login item at end with properties {path:"/Applications/Hammerspoon.app", hidden:false}'Ignore this quirky output:
login item UNKNOWN
This does work,
which you can verify by running the above osascript command again to see it's in the list of login items.
You can also see this in the Mac UI of Settings Settings -> General -> Login Items (Ventura / Sonoma):
open "x-apple.systempreferences:com.apple.LoginItems-Settings.extension"or System Preferences -> Users & Groups -> Login Items (Monterey / Big Sur):
open "x-apple.systempreferences:com.apple.preference.users?LoginItems"To add it if not already added:
osascript <<EOF
tell application "System Events"
if not (exists login item "Hammerspoon") then
make login item at end with properties {path:"/Applications/Hammerspoon.app", hidden:false}
end if
end tell
EOFYou can use native AppleScript to generate a temporary desktop pop-up notification in the top right corner of the screen like this:
osascript -e 'display notification "Your message here" with title "Automation" subtitle "Status Update"'These notifications stay in your notification history until dismissed. You can see them if you click on the clock in the top right corner to open the notification centre.
WARNING: If user has Do Not Disturb set, then these notifications may be suppressed.
If it's important you can use an alert instead as shown below.
To generate a pop-up alert notification that requires manual dismissal:
osascript -e 'display alert "Important Message Title" message "Backup completed successfully" as informational'To generate a pop-up in the middle of the screen that disappears after 5 seconds:
osascript -e 'display dialog "This will vanish in 5 seconds..." with title "Self-Destructing Pop-up" buttons {"OK"} default button "OK" giving up after 5'If it expires, the command outputs this text:
button returned:, gave up:true
If you click the OK button to dismiss it, returns this text:
button returned:OK, gave up:false
This allows you to capture the output in a script and then take some fallback action.
Using graphical Disk Utility is easiest:
open -a 'Disk Utility'Mac built in System Settings -> General -> Storage will give a good high-level overview of what
is taking up your disk space:
open "x-apple.systempreferences:com.apple.settings.Storage"You can see this Apple support article on optimizing space.
My favourite of all time is Disk Inventory X:
brew install disk-inventory-xopen -a 'Disk Inventory X' /GrandPerspective is another similar GUI disk space analysis app:
brew install --cask grandperspectiveopen -a GrandPerspective /OmniDiskSweeper is another option:
brew install --cask omnidisksweeperopen -a OmniDiskSweeper /BaoBab is available on both Linux & Mac:
brew install baobabbaobab /But for CLI junkies there is also ...
Aside from the classic portable unix df and du commands...
... there is this cool interactive 'ncurses du' which allows you to easily drill down to find the biggest directories and files:
brew install ncdusudo ncdu /The biggest directories and files are automatically sorted to the top for convenience at each level you drill in to.
Type ? for the interactive help menu.
USB bus makes a huge difference between USB 2 and USB 3.
On a Time Machine restore of my hosed mac, this was the difference between 80-90 hour s and 2-3 hours projected completion time.
system_profiler SPUSBDataTypeEven among USB 3.1 look at the speed difference different cables can make with identical model SanDisk Extreme Pro SSD disks:
system_profiler SPUSBDataType | grep -e Bus -e Speed -e Manufacturer USB 3.1 Bus:
Speed: Up to 480 Mb/s
Manufacturer: SanDisk
USB 3.1 Bus:
Speed: Up to 10 Gb/s
Manufacturer: SanDisk
USB 3.1 Bus:
Part 1 - List, Verify, Repair, Rename, Erase volumes
Part 2 - Partition, Format, Split / Merge Partitions
Part 3 - Create .dmg disk images from a Volume / Folder, Encrypted Disk Image, Resize Image, Restore Image
diskutil listdiskutil mount and diskutil mountDisk are the same
diskutil mount /dev/disk4s2diskutil unmount /dev/disk4s2Unmount all filesystems on a disk:
diskutil unmountDisk force "/dev/$disk"or by volume location:
diskutil unmount "/Volumes/$NAME"Mount a partition read-only if having trouble and trying to recover data:
diskutil mount readOnly /dev/disk4s2Mount at a different location to the default /Volumes/<partition_metadata_name>:
diskutil mount /dev/disk4s2 -mountPoint /path/to/dirMount / unmount partitions on a whole disk by reading its partition table:
diskutil mountDisk disk10diskutil unmountDisk disk10Verify a volume:
diskutil verifyVolume "/Volumes/$NAME"Repair volume:
diskutil repairVolume "/Volumes/$NAME"diskutil verifyPermissions "/Volumes/$NAME"diskutil repairPermissions "/Volumes/$NAME"These operations are risky as you might get the disk wrong - it's much easier and safer to do this in Disk Utility!
Format a partition:
Risky because there is no confirmation and you could end up doing this to the wrong disk!!
diskutil eraseDisk "$filesystem" "$name" "/dev/$diskN"See which filesystems are available for formatting:
diskutil listFilesystemsFormattable file systems
These file system personalities can be used for erasing and partitioning.
When specifying a personality as a parameter to a verb, case is not considered.
Certain common aliases (also case-insensitive) are listed below as well.
-------------------------------------------------------------------------------
PERSONALITY USER VISIBLE NAME
-------------------------------------------------------------------------------
Case-sensitive APFS APFS (Case-sensitive)
(or) APFSX
APFS APFS
(or) APFSI
ExFAT ExFAT
Free Space Free Space
(or) FREE
MS-DOS MS-DOS (FAT)
MS-DOS FAT12 MS-DOS (FAT12)
MS-DOS FAT16 MS-DOS (FAT16)
MS-DOS FAT32 MS-DOS (FAT32)
(or) FAT32
HFS+ Mac OS Extended
Case-sensitive HFS+ Mac OS Extended (Case-sensitive)
(or) HFSX
Case-sensitive Journaled HFS+ Mac OS Extended (Case-sensitive, Journaled)
(or) JHFSX
Journaled HFS+ Mac OS Extended (Journaled)
(or) JHFS+
Rename a disk:
diskutil rename "$volume_name" "$new_volume_name"These operations are risky as you might get the disk wrong - it's much easier and safer to do this in Disk Utility!
APFS requires GPT partition table.
disk="disk4"
partition_table="GPT"
name="MyVolume"
filesystem="APFSX" # AppleFS case-sensitive, found from 'diskutil listFilesystems' above
size="0b" # integer + units suffix (b, m or g for bytes, megabytes or gigabytes) - '0b' uses all spacediskutil partitionDisk "/dev/$disk" "$partition_table" "$filesystem" "$name" "$size"diskutil partitionDisk /dev/"$disk" "$partition_table" "$filesystem" "First" "$size" \
"$filesystem" "Second" "$size" \
"$filesystem" "Third" "$size" \
"$filesystem" "Fourth" "$size" \
"$filesystem" "Fifth" 0b # '0b' to use up all remaining spacePartition splitting doesn't seem to work with APFS, only macOS Extended, as APFS tells you to
diskutil apfs deleteContainer disk10 instead which leaves you with free space to create a new partition.
If you partitioned it without APFS, reformat the disk with APFS:
diskutil eraseDisk APFS "$name" "/dev/$disk"Alternatively, if you already have GPT parititioned disk and only want to format the partition:
diskutil eraseVolume "APFSX" "MyEncryptedDisk" "/dev/${synthesized_disk}s1"Notice the disk here will be different to the physical disk, it'll be the synthesized disk of an increment higher disk
number as shown by diskutil list.
Then encrypt the APFS container partition, in this case the first partition s1:
diskutil apfs encryptVolume "/dev/${synthesized_disk}s1" -user disk -passphrase "$password"Or better pass via stdin:
diskutil apfs encryptVolume "/dev/${synthesized_disk}s1" -user disk -stdinpassphrase <<< "$password"If you omit the <<< "$passphrase" part of the command, it'll wait for you without a prompt to enter the passphrase
interactively on the command line, so not storing it in shell history (alternatively if using Bash unset HISTFILE to prevent it
being written to ~/.bash_history):
diskutil apfs encryptVolume "/dev/${synthesized_disk}s1" -user disk -stdinpassphraseDecrypt the volume:
diskutil apfs decryptVolume "${synthesized_disk}s1" -user disk -stdinpassphrase <<< "$password"If you want to add a password hint you'll need to do this via the macOS GUI via Disk Utility instead:
open -a "Disk Utility"To create an encrypted volume within a file...
From the top menu in Disk Management:
File -> New Image -> Blank Image:
- Set the File Name
- Set the fields at the bottom:
Volume Name- how it appears when mountedEncryption- set to 256-AES encryptionSize- eg. 100mbImage Format- set tosparse disk image(notsparse bundle disk imagewhich uses a directory with 8MB fragments, which is more efficient for backups but harder to manage as you need to keep the directory structure intact).
Stick if on an APFS encrypted USB using the sections above for extra security.
cd /Volumes/MyEncryptedUSBhdiutil create -encryption AES-256 -size 100m -fs APFS -type SPARSE -volname "$name" "$name.dmg"hdiutil attach "$name.dmg"hdiutil deattach "$name.dmg"Either use Disk Utility above, a command like diskutil eraseDisk ... or the more portable unix command dd with a
custom command like this to do a moderate 3 pass overwrite
(tune number of passes variable to suit your level of data recovery paranoia, eg. DoD standard 7 passes):
WARNING: disk numbers may shunt up in numbers as you insert more removal drives, especially for 'synthesized' virtual disks that display for volume containers
passes=3
time \
for number in $(seq $passes); do
echo pass $number
echo
time sudo dd if=/dev/urandom of=/dev/disk4 bs=1M
echo
doneNote: multiple passes are only for old inaccurate HDDs rotating mechanical metal platter disk. For SSDs, you only need a single pass.
List services:
sudo launchctl listLoad and start a service from a plist file:
sudo launchctl load -F "/System/Library/LaunchDaemons/$name.plist"
sudo launchctl start "com.apple.$name"Stop and unload a service:
sudo launchctl stop "com.apple.$name"
sudo launchctl unload "/System/Library/LaunchDaemons/$name.plist"See dhcp.md for a practical example of using this for the built-in tftp server for PXE boot installing Debian off your Mac.
You can also go to Finder and delete the App with Ctrl-Backspace
which gives a pop-up to remove its system extensions (also stops its services),
eg. for otherwise stubborn services like Avira antivirus.
osascript -e "set volume output volume 50"Install switchaudio-osx:
brew install switchaudio-osxList sound outputs:
SwitchAudioSource -a -t outputHari’s AirPods Pro
BlackHole 2ch
MacBook Pro Speakers
Microsoft Teams Audio
Multi-Output Device
Choose one:
SwitchAudioSource -s "MacBook Pro Speakers"SwitchAudioSource -s "Hari’s AirPods Pro"SwitchAudioSource -s "Multi-Output Device"Capture the songs from your favourites movies or TV shows while listening with headphones.
See the instructions on the audio page.
Hammerspoon is a system event handler for Mac.
The code is written in Lua.
brew install hammerspoon --caskThen create a ~/.hammerspoon/init.lua to register your event handlers.
My code is found at
HariSekhon/Hammerspoon.
mkdir -p -v ~/githubgit clone https://github.com/HariSekhon/Hammerspoon ~/github/hammerspoonln -svFhw ~/github/hammerspoon ~/.hammerspoonOutput:
/Users/hari/.hammerspoon -> /Users/hari/github/hammerspoon
As documented on this Audio page section I use this to be able to Shazam songs from movies or TV shows while watching them on AirPods, and used this code to automatically switch to the multi-output audio device to be able to do so.
Finally, start Hammerspoon, you should see its icon in the menu bar.
open -a HammerspoonSet Hammerspoon to start at login (you can tick this in the Hammerspoon Preferences UI) or just run this:
osascript -e 'tell application "System Events" to make login item at end with properties {path:"/Applications/Hammerspoon.app", hidden:false}'Optionally allow pop-up desktop notifications from Hammerspoon so that your code can notify you when it's done something for you (I recommend Banners that automatically disappear without having to click them).
System Settings -> Notifications ->Hammerspoon:
open "x-apple.systempreferences:com.apple.Notifications-Settings.extension?bundleId=org.hammerspoon.Hammerspoon"open -a "Keychain Access"See the Binaries Debugging doc for commands to examine and work with binaries.
Macs and many computers don't come with CD/DVD anymore to save space, so you can either buy an external USB dvd-writer or create bootable USBs.
To create a bootable USBs from ISO image files intended for CD/DVDs in order to use them to install Linux or use a disk wiping distro like DBAN or ShredOS, you can download Etcher or use mac_iso_to_usb.sh from DevOps-Bash-tools:
mac_iso_to_usb.sh "$iso" # /dev/disk4- UNetbootin app from github
- DiskUtility
- CLI
Set your filename in a variable so the following commands can be executed as is without editing:
export ISO="memtest86+-5.01.iso"Convert it to make it bootable - will automatically add .dmg suffix => .img.dmg:
hdiutil convert -format UDRW -o "$ISO.img" "$ISO"Figure out which is the USB disk - be careful or you'll destroy your system!
diskutil listdiskutil unmountDisk /dev/diskNTip: prefixing disk with 'r' uses raw disk which is faster:
sudo dd if="$ISO.img" of=/dev/rdiskN bs=1m # or 1Mdiskutil eject /dev/diskNBurn CD - insert blank CD then:
hdiutil burn "$ISO"Use at your own risk.
There is a reason I put this just before the Troubleshooting section... 😉
See Mobile Builds doc.
If you choose to use the device vendor's encryption on your external drive, this usually requires an app provided by the vendor, it may seem fine at first as you'll be unable to back up and restore in normal full macOS installation but if you've hit a bootup problem and need to work in recovery mode, then you'll be unable to unlock and access the vendor encrypted disk as the vendor software will not work in macOS recovery mode which is a very cut down version.
In that case, your options will be to use another disk or do an emergency file backup & recovery.
See the Emergency File Backup from Recovery Mode and Reinstall macOS & Restore Data sections under Troubleshooting further down.
You can do this in the Time Machine UI, but it's easier to do this on the command line:
sudo tmutil addexclusion -p "$path"Omitting the -p switch sets it on the directory attributes rather than in Time Machine, making it sticky if the folder
is moved.
Unfortunately without the -p switch the folder does not appear in the Time Machine UI,
and you can only find this by querying all the directories one by one
xattr -p com.apple.metadata:com_apple_backup_excludeItem "$path"
which is of course a terribly non-scalable O(1) operation to try to find what is excluded...
So ensure you use the -p switch to record it in the UI instead for clarity, at the expense of not tracking the
directory moves.
WARNING: omitting the -p switch leaves you blind and you may get a shock that a directory you thought was backed up is in fact
not
If you have played around with this and want to do a deep search, use this script from DevOps-Bash-tools:
mac_backup_find_excluded_paths.shThe following script in DevOps-Bash-tools adds the common cache paths to the exclusion list in the correct way
that you can see in the UI.
You can quickly add your local repo's build and Pods directories as args too:
mac_backup_exclude_paths.sh "$PWD/build" "$PWD/Pods"This attempts to remove the xattr on the path itself:
sudo tmutil removeexclusion "$path"Use -p if it was set at global path level using sudo tmutil addexclusion -p ...
sudo tmutil removeexclusion -p ~/github/go-tools/athIf you get an error like this:
sudo tmutil removeexclusion ~/github/go-tools/ath/Users/hari/github/go-tools/ath: Error (-43) while attempting to change exclusion setting.
Compare the path to the paths in:
defaults read /Library/Preferences/com.apple.TimeMachine SkipPathsTry using -p if it was set with that and also the exact absolute path /Users/hari/github/... matching the above
output instead of ~/github/...:
sudo tmutil removeexclusion -p /Users/hari/github/go-tools/athtmutil startbackupBackup status:
tmutil statusCancel backup:
tmutil stopbackupList time machine backups:
tmutil destinationinfoOnly the disks that show a line Mount Point like this are currently plugged in and mounted to be available:
Mount Point : /Volumes/<name>...
Determine the Mount Point of the backup disk:
BACKUP_MOUNTPOINT="$(tmutil destinationinfo | awk -F " : " '/^Mount Point/{print $2; exit}' | tee /dev/stderr)"List all backups:
tmutil listbackupsThe latest one is at the bottom of the list as it's in date timestamp ascending order.
Save the latest one:
LATEST_BACKUP="$(tmutil latestbackup | tee /dev/stderr)"or
LATEST_BACKUP="$(tmutil listbackups | tail -n 1 | tee /dev/stderr)"Sometimes this will print a path like this that doesn't exist:
/Volumes/.timemachine/12A345B6-7CDE-8FA9-0B1C-2D34567EF890/1234-56-78-901234/2025-02-21-012346.backup/2025-02-21-012346.backup
when in fact it would be:
$BACKUP_MOUNTPOINT/2025-02-21-012346.backup
So check the path and try different variations for the LATEST_BACKUP path.
Restore a file:
tmutil restore "$LATEST_BACKUP/Data/$PWD/$filename" "$PWD/$filename"To handle these variations and test the backups for the latest version which has it, from DevOps-Bash-tools:
mac_restore_file.sh "$filename"
Sometimes it's perplexing why Time Machine is taking so long or backing up large volume of hundreds of GB when you know nothing much has changed in your data or applications since the last backup:
After trying many crappy tmutil commands that don't work any more and random things off the internet,
it turns out this old skool method is the most reliable to find out what is going in there:
sudo du -max /Volumes/*/$(date '+%F')-*.inprogress/ | sort -k1n | tail -n 1000This is scripted more easily in mac_backup_du_in_progress.sh in DevOps-Bash-tools
which will try for an inprogress dir for today or yesterday if today's one is not found,
as if you're a night owl like me the backup might have started before midnight.
If the backup has finished, then just find the latest backup and do the same:
sudo du -max /Volumes/*/$(date '+%F')-*.previous/ | sort -k1n | tail -n 1000I found out this unexpected culprit:
1660 2025-12-08-224300.inprogress//Macintosh HD - Data/System/Library/AssetsV2/com_apple_MobileAsset_MacSoftwareUpdatemacOS was wasting my time backing up the software update download 😒.
I've added this to:
mac_backup_exclude_paths.shin the Exclude Paths From Backups section above.
Time Machine requires formatting a complete disk to structure it correctly.
Do not copy data to your Time Machine volume, disk snapshots may prevent space reclamation when you try to delete your files.
Instead, create an additional volume using Disk Utility or the command line and store your files on the second Data volume.
Both the Time Machine volume and the Data volume on the disk will share the overall disk space dynamically as they fill up, but this way, removing files from the Data volume will actually reclaim the space from the overall disk as it it will not be affected by time machine snapshots.
To reclaim space on the external disk...
Find and delete large directories such as .TemporaryItems, .fseventsd, .Trashes
sudo rm -rf "/Volumes/$NAME/.fseventsd" \
"/Volumes/$NAME/.TemporaryItems" \
"/Volumes/$NAME/.Trashes"sudo mdutil -i off "/Volumes/$NAME"sudo mdutil -E "/Volumes/$NAME"If it still remains:
sudo rm -rf "/Volumes/$NAME/.Spotlight-V100"sudo rm -rf "/Volumes/$NAME/.DocumentRevisions-V100"To allow space to be reclaimed:
sudo killall mds mds_stores revisionddf -h "/Volumes/$NAME"Try forcing it by opening this site which doesn't use SSL, therefore allowing the captcha portal to intercept and redirect to itself:
Check you haven't set explicit hardcoded DNS servers in your network settings (eg. public DNS) as that may prevent the captcha portal address from resolving.
This is because some environments rely on resolving the captcha portal address using the local DNS server (configured by DHCP, which you aren't using if you hardcode static IP DNS) if the gateway firewall is not configured to intercept public DNS requests to redirect them to the local DNS which can return the captcha portal IP.
You can quickly set the DNS back to DHCP using this command (en0 is your wifi network card):
sudo networksetup -setdnsservers en0 "Empty"Once I did that, and checking the DNS:
cat /etc/resolv.confThe output looked like this:
#
# macOS Notice
#
# This file is not consulted for DNS hostname resolution, address
# resolution, or the DNS query routing mechanism used by most
# processes on this system.
#
# To view the DNS configuration used by this system, use:
# scutil --dns
#
# SEE ALSO
# dns-sd(1), scutil(8)
#
# This file is automatically generated.
#
nameserver 10.4.0.1
After this the captcha portal loaded correctly using the local network's DNS.
You can also see your DNS settings in the UI or using this more native mac command, but the output is long and messy:
scutil --dnsIf you get this IP address conflict message pop-up:
Another device on the network is using your computer’s IP address (192.168.1.14).
Try connecting again later. If you continue to have problems, change the IP address of this computer or the IP address of the other device. Contact the network administrator if you need more information.
This is usually caused by either a static IP address misconfiguration, or possibly switching between 2.4GHz and 5GHz wifi networks on the same network (although this is rare).
If you're using static IP addresses, configure a different static IP on your device or the other device to avoid the conflict.
If you're using DHCP on a Wifi network, refresh to using another IP address lease.
You can try to disconnect and reconnect to the network, or release and request using the command line.
Unfortunately the DHCP server (usually the wifi router) will usually re-issue you the same IP, resulting in the same problem. Rebooting the wifi router or if it's an actual DHCP server, restarting the DHCP service or flushing its DHCP memory would be required.
Release current IP:
sudo ipconfig set en0 noneDHCP request new IP:
sudo ipconfig set en0 DHCPIf you are allocated the same IP again you may get the same pop-up error, in which case:
A late ditch hack would be to simply set a different unused static IP (guess one at the end of the network block range) on the same DHCP network to bypass the issue and then unset it later.
sudo ipconfig set en0 MANUAL 192.168.1.15 255.255.255.0You then also need to add a default route:
sudo route add default 192.168.1.1and set the DNS to use both the router and a public DNS in case the router doesn't permit DNS egress traffic (this happened to me even on a residential router in Novi Sad, Serbia):
sudo networksetup -setdnsservers Wi-Fi 192.168.1.1 8.8.8.8If the DNS set doesn't appear in /etc/resolve.conf, see the next section.
Symptom: no outbound DNS packets being sent when doing a simple DNS lookup command, it turned out the DNS servers were not being respected.
Trace DNS packets in one terminal:
sudo tcpdump -i en0 -n port 53Run DNS lookup in another terminal:
host google.comNo output from tcpdump in the first terminal showed nothing was being sent.
Checked the contents of /etc/resolv.conf:
cat /etc/resolv.confThe file contents did not show any DNS servers set from the command in the above section
(sudo networksetup -setdnsservers ...):
You can run the more native mac command:
scutil --dnsand will see tha the mac resorts to the internet root DNS servers (which are not reachable due to egress filtering):
DNS configuration
resolver #1
flags :
reach : 0x00000000 (Not Reachable)
resolver #2
domain : local
options : mdns
timeout : 5
flags :
reach : 0x00000000 (Not Reachable)
order : 300000
resolver #3
domain : 254.169.in-addr.arpa
options : mdns
timeout : 5
flags :
reach : 0x00000000 (Not Reachable)
order : 300200
resolver #4
domain : 8.e.f.ip6.arpa
options : mdns
timeout : 5
flags :
reach : 0x00000000 (Not Reachable)
order : 300400
resolver #5
domain : 9.e.f.ip6.arpa
options : mdns
timeout : 5
flags :
reach : 0x00000000 (Not Reachable)
order : 300600
resolver #6
domain : a.e.f.ip6.arpa
options : mdns
timeout : 5
flags :
reach : 0x00000000 (Not Reachable)
order : 300800
resolver #7
domain : b.e.f.ip6.arpa
options : mdns
timeout : 5
flags :
reach : 0x00000000 (Not Reachable)
order : 301000
Diagnosis: it was an ordering problem on network interfaces.
Solution: I put the wifi network first in the ordering.
This is easiest done in the UI: System Settings -> Network -> ... drop down (near the bottom right)
-> Set Service Order -> Drag Wi-Fi to the top of the list.
On the command line, you first need to find the names of the all the network services:
sudo networksetup -listnetworkserviceorderand then list all of them in the ordered you want (the command fails if you only put some).
To get just the clean list:
sudo networksetup -listnetworkserviceorder | awk '/^\([[:digit:]]*\)/ { $1=""; print}' | sed 's/^[[:space:]]*//'Then order them as you want with the Wi-Fi network at the front so it uses the DNS servers from there.
sudo networksetup -ordernetworkservices "Wi-Fi" "Display Ethernet" "Thunderbolt Bridge" "iPhone USB" "ProtonVPN"After that the DNS servers appeared in /etc/resolv.conf and scutil --dns output and DNS started working again.
On another occasion the above didn't work, nor did removing the Wi-Fi profile from en0 (had to create a temp one to do this) and going back through the whole thing, in which case it can be a corruption of configuration registry, try a reboot.
sudo du -csh "/Volumes/$NAME"2.2T /Volumes/$NAME
2.2T total
df -h "/Volumes/$NAME"Filesystem Size Used Avail Capacity iused ifree %iused Mounted on
/dev/disk5s2 3.6Ti 3.6Ti 59Gi 99% 4.8M 618M 1% /Volumes/$NAME
This can be caused by files being held open (kill the process):
sudo lsof +L1Or in my case Time Machine APFS snapshots which are counted by df but not by du:
tmutil listlocalsnapshots "/Volumes/$NAME"or if it's the root disk:
tmutil listlocalsnapshots /You can either tell macOS to try to delete enough snapshots to free 100GB (number is in bytes), and on level from 1 - 4 of aggressiveness, ie. you need the space reclaimed urgently:
sudo tmutil thinlocalsnapshots / 100000000000 4Or you can try to delete snapshots explicitly or delete iterate to delete all the snapshots (OS update snapshots do not get deleted even when ordered to):
for snapshot in $(tmutil listlocalsnapshots / | command ggrep -oP '\d{4}-\d\d-\d\d-\d+'); do
sudo tmutil deletelocalsnapshots "$snapshot"
doneThere is a script in DevOps-Bash-tools for this called:
mac_delete_local_snapshots.shIf you get this error:
/Volumes/NAME is an APFS backup disk. Use 'tmutil listbackups' to list APFS backup snapshots.
then:
tmutil listbackups/Volumes/.timemachine/A1BCD23E-45F6-78AB-901C-2DE34567FAB8/2025-03-28-015336.backup/2025-03-28-015336.backup
I deleted the backup so I could free up space, but you may want to keep your backup:
sudo tmutil delete -d "/Volumes/$NAME" -t 2025-03-28-0153361 backups deleted
Another thing to check is for .interrupted and .incomplete directories of backups that failed to complete, such as
the machine sleeping and disconnecting the external disk.
cd "/Volumes/$NAME" && rm -fr *.previous *.interruptedAfter this du and df reconciled.
If Cmd-Space
Spotlight pop up search is failing
to find an app like Spotify.app and instead only giving you Google Chrome or other results wrong results,
try erasing and re-indexing the Spotlight index:
sudo mdutil -E /This fixed it for me.
Also check that you haven't excluded a location under System -> Siri & Spotlight ->
Spotlight Privacy (exclusions at the bottom).
xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
Switch to full Xcode:
sudo xcode-select -switch /Applications/Xcode.app/Contents/DeveloperVerify the change:
xcode-select -pOutput:
/Applications/Xcode.app/Contents/Developer
Accept license if you have to:
sudo xcodebuild -licenseClicking the App icon results in this error pop-up:
The application “Spotify.app” can’t be opened.
Trying to open it via the command line:
open -a Spotifyresults in this error:
The application /Applications/Spotify.app cannot be opened for an unexpected reason, error=Error Domain=RBSRequestErrorDomain Code=5 "Launch failed." UserInfo={NSLocalizedFailureReason=Launch failed., NSUnderlyingError=0x6000039a33c0 {Error Domain=NSPOSIXErrorDomain Code=153 "Unknown error: 153" UserInfo={NSLocalizedDescription=Launchd job spawn failed}}}
Checking its digital signature:
spctl --assess --verbose /Applications/Spotify.appOutput:
/Applications/Spotify.app: invalid Info.plist (plist or signature have been modified)Open the logging console to debug:
open -a ConsoleStart streaming and then enter a filter in the top right box eg. spotify.
I saw logs like these:
default 11:24:53.815483-0500 amfid /Applications/Spotify.app/Contents/MacOS/Spotify not valid: Error Domain=AppleMobileFileIntegrityError Code=-420 "The signature on the file is invalid" UserInfo={NSURL=file:///Applications/Spotify.app/Contents/MacOS/Spotify, NSLocalizedDescription=The signature on the file is invalid}
default 11:24:53.822324-0500 kernel mac_vnode_check_signature: /Applications/Spotify.app/Contents/MacOS/Spotify: code signature validation failed fatally: When validating /Applications/Spotify.app/Contents/MacOS/Spotify:
The code contains a Team ID, but validating its signature failed.
Please check your system log.
default 11:24:53.822376-0500 kernel proc 41565: load code signature error 4 for file "Spotify"
default 11:24:53.822927-0500 kernel ASP: Security policy would not allow process: 41565, /Applications/Spotify.app/Contents/MacOS/Spotify
It is not clear how this application developed this signature error, perhaps it tried to auto-update and was interrupted and failed, leaving a broken signature.
Solution: Reinstall or Upgrade the app to get the signature to be verified again.
If you have installed via Homebrew (even if you haven't, brew casks can replace manually installed
apps under /Applications):
brew reinstall spotifyOr if there is a newer version just upgrade to that:
brew upgrade spotifyAfterwards the signature verification should succeed:
spctl --assess --verbose /Applications/Spotify.appOutput:
/Applications/Spotify.app: accepted
source=Notarized Developer ID
or for more details:
codesign -dv --verbose=4 /Applications/Spotify.appI got the next error when trying to reopen it, but it was an easy fix in this next section:
If when opening you get this error:
"Spotify.app" is damaged and can't be opened. You should move it to the Bin.
Just accept to move it to the bin and then reinstall it again:
brew reinstall spotifyand then it will open normally:
open -a SpotifyOften with this pop-up error:
The application “Microsoft Remote Desktop.app” is not open anymore.
This is the same whether you open it via an icon or Spotlight Cmd + Space and autocomplete.
This even happens with Activity Monitor.
Same with IntelliJ IDEA:
$ open -a "IntelliJ IDEA CE"
The application /Applications/IntelliJ IDEA CE.app cannot be opened for an unexpected reason, error=Error Domain=NSOSStatusErrorDomain Code=-600 "procNotFound: no eligible process with specified descriptor" UserInfo={_LSLine=4141, _LSFunction=_LSOpenStuffCallLocal}Same with Settings:
$ open -a "Settings"
The application /System/Applications/System Settings.app cannot be opened for an unexpected reason, error=Error Domain=NSOSStatusErrorDomain Code=-600 "procNotFound: no eligible process with specified descriptor" UserInfo={_LSLine=388, _LSFunction=_LSAnnotateAndSendAppleEventWithOptions}Same with Microsoft Remote Desktop.
Clicking the icon results in a pop up with this error:
The application “Activity Monitor.app” is not open anymore.
The application “Microsoft Remote Desktop.app” is not open anymore.
open -a "Microsoft Remote Desktop"
The application /Applications/Microsoft Remote Desktop.app cannot be opened for an unexpected reason, error=Error Domain=NSOSStatusErrorDomain Code=-600 "procNotFound: no eligible process with specified descriptor" UserInfo={_LSLine=388, _LSFunction=_LSAnnotateAndSendAppleEventWithOptions}Only Finder seems to work:
open -a "Finder"Fix: Reboot the Mac... tried a few other things like killing all the stale processes but none of them worked and when your Terminal window gets closed and you get the same error trying to re-open another one, it's game over. Reboot.
APFS requires a small amount of space to even be able to delete files.
Workarounds:
- Empty Trash
- try
echo > "$filename"ortruncate -s 0 "$filename"instead ofrm - delete the
VMapfs volume containing the sleep image and give enough space for APFS to maneuvre again
If even after freeing a bit of space from an adjacent volume like VM you still get the no space left on device error
from rm then it's possible you have catastrophic APFS corruption of the metadata.
This has happened to me under heavy writes and deletes at the same time, and in that case the only way to recover is to reinstall macOS to recreate the special Data linked partition and then restore from Time Machine Backup.
See the Reinstall macOS & Restore Data section below, but first, do your backups!
If you hit the above APFS catastrophic metadata corruption and are unable to delete anything from a drive to recover and start using it again, then your only choice is to reinstall macOS and then restore your data from your latest time machine backup.
If you are able to plug your Time Machine backup disk in, take a full backup.
If you cannot take a time machine backup or your machine no longer boots then follow the next section.
If your macOS fails to boot due to the full Data disk then you will need to enter Recovery Mode and do your emergency backup and recovery from there.
On newer Apple Silicon Macs hold the power button for 5-10 seconds to start up to the Options menu.
In the menu, click Options to the right, and then Recovery Mode.
If your existing backups are not completely up to date (as is often the case if you're on a laptop and therefore not leaving your backup disk plugged in to for hourly backups due to moving moving around), then you will need to do an emergency time machine backup from recovery mode and then restore that.
Once you've taken a backup in recovery mode you'll then need to reinstall macOS and restore your data using the latest Time Machine backup as per the section below.
If instead you want to a potentially more selective emergency file level backup, if you are able to boot macOS normally then run rsync to copy your files off to the backup disk.
If you're not able to boot macOS though, you'll need to do an emergency file backup as per the next section.
If you have made the mistake of using vendor encryption on your external disk then you will not be able to unlock it in macOS recovery mode to take a time machine backup and must use another disk to do either a time machine backup or a file level backup.
If you can't access your time machine backup disk from recovery mode due to it being vendor encrypted, then you'll have to get another disk and either do a time machine backup to that or do a file level backup.
The file level backup has the benefit of giving you the option of only backing up a few key paths such as your latest
work directories (be careful you don't miss anything important though).
For this, the trusty old rsync command is recommended.
Recovery Mode is extremely limited though, it doesn't even have rsync,
so you'll need to download the right rsync binary using your phone or another computer from here:
https://download.samba.org/pub/rsync/binaries/
For macOS specifically:
https://download.samba.org/pub/rsync/binaries/macos-12.6-arm64/latest.tar.gz
and then transfer it to the portable disk to use it in recovery mode.
tar zxvf latest.tar.gzrsync -av ...You cannot just delete and recreate the internal home Data APFS volume because it is a special volume.
It must be paired with the installation at install time.
This means that under catastrophic APFS corruption failure scenario you need to reinstall macOS and then restore your Time Machine backup.
On newer Apple Silicon Macs hold the power button for 5-10 seconds to start up to the options menu.
Under Options there is a hidden partition that allows you to reinstall macOS and recreate the Data partition.
First, however, you need to erase the entire Macintosh HD container, not the volume, but the container itself.
Using Disk Utility in Recovery Mode, Erase the Container holding Macintosh HD with the following options:
| Field | Value |
|---|---|
| Name | Macintosh HD |
| Format | APFS |
| Scheme | GUID Partition Map (if it shows this option) |
Then exit Disk Utility and from the Options menu click the option to Reinstall macOS.
The reinstall will probably take 1-2 hours.
After that, restore your latest Time Machine backup, which if you've got a good fast SSD and USB 3 cable took me 2-3 hours for 4TB.
If you've had to do an Emergency File Backup from Recovery Mode, then rsync the newer files that changed since your last Time Machine backup.
This includes your MacBook Pro - 128GB RAM ftw...
ps. gif screencapture scripts for the two styles, above and below, are in the DevOps-Bash-tools repo.
Ported from various private Knowledge Base pages 2010+