It looks like the command-line defaults
tool can do this.
To dump all of the preferences system-wide (massive amounts of data), use defaults read
:
$ defaults read
{
".GlobalPreferences_m" = {
};
"Apple Global Domain" = {
AKLastEmailListRequestDateKey = "2022-01-31 03:14:11 +0000";
AKLastIDMSEnvironment = 0;
"AMD4.Clock" = "1.603401e+09";
AppleAccentColor = 4;
...
To dump all of the preferences in a single domain, use defaults read
followed by the name of the domain. For instance, to see TextEdit preferences (com.apple.TextEdit domain):
$ defaults read com.apple.TextEdit
{
AVPlayerViewShowsDurationInsteadOfTimeRemainingDefaultsKey = 1;
NSFontPanelAttributes = "1, 0";
NSNavLastRootDirectory = "~/Desktop";
NSNavLastUserSetHideExtensionButtonState = 1;
...
A domain can also be specified by application name with the -app
argument:
$ defaults read -app TextEdit
{
AVPlayerViewShowsDurationInsteadOfTimeRemainingDefaultsKey = 1;
NSFontPanelAttributes = "1, 0";
NSNavLastRootDirectory = "~/Desktop";
NSNavLastUserSetHideExtensionButtonState = 1;
...
But this doesn’t seem to work for all applications. For instance, -app finder
gives me an error, even though the com.apple.finder
domain works. I suspect the human-visible application names aren’t always the names used internally by the OS.
Finally, you can specify the path to the plist file holding the preferences (must be an absolute path - beginning with either a /
or a ~
character) instead of a domain or app name:
$ defaults read ~/Library/Preferences/com.apple.TextEdit.plist
{
NSNavLastRootDirectory = "~/Documents/Word Processing docs";
NSNavLastUserSetHideExtensionButtonState = 0;
NSNavPanelExpandedSizeForSaveMode = "{712, 473}";
Notice how this isn’t the same information as what we got from com.apple.TextEdit
or -app TextEdit
. That’s because the application isn’t actually using that file - it’s a leftover preference file from some earlier version of macOS. (In my case, the file is dated April 30, 2020, which was when I was running Sierra on my previous computer. It got migrated forward and has not been used since then.)
The location of the active preference file for TextEdit is within its sandbox-container:
$ defaults read ~/Library/Containers/com.apple.TextEdit/Data/Library/Preferences/com.apple.TextEdit.plist
{
AVPlayerViewShowsDurationInsteadOfTimeRemainingDefaultsKey = 1;
NSFontPanelAttributes = "1, 0";
NSNavLastRootDirectory = "~/Desktop";
NSNavLastUserSetHideExtensionButtonState = 1;
Which is why it’s better to always use a domain name instead of the path to a file. The domain will go to the right place, which might not be the file you were thinking of. (The man page also says that the tool’s ability to read a specific file may be going away in the future, to be replaced with a different generic plist-access tool).
Of course, for many apps, dumping the entire file is going to be a massive amount of data, and you often don’t care about it all. So you can also choose to specify a single key from a domain. You can also use the read-type command to get the key’s data type. For instance:
$ defaults read-type com.apple.finder CopyProgressWindowLocation
Type is string
$ defaults read com.apple.finder CopyProgressWindowLocation
{1428, 665}
$ defaults read-type com.apple.finder DesktopViewSettings
Type is dictionary
$ defaults read com.apple.finder DesktopViewSettings
{
IconViewSettings = {
arrangeBy = grid;
backgroundColorBlue = 1;
backgroundColorGreen = 1;
backgroundColorRed = 1;
backgroundType = 0;
gridOffsetX = 0;
gridOffsetY = 0;
gridSpacing = 43;
iconSize = 32;
labelOnBottom = 1;
showIconPreview = 1;
showItemInfo = 0;
textSize = 10;
viewOptionsVersion = 1;
};
}
Unfortunately, I couldn’t find any obvious way to select a key from within a nested array or dictionary with the defaults
command. So you may not be able to select nested keys without reading the entire top-level key and parsing the results.