My recent tip about using Keyboard Maestro to toggle the visiblity of hidden items in Finder (which turned out to be irrelevant for Sierra users; just hold ⌘⌥.) works by checking a hidden macOS preferences setting. In this case, I checked for the existence of the AppleShowAllFiles key, which let me toggle the visiblity of invisible files based on the result of the check.
Controlling a macro—or a shell script or AppleScript—by checking (visible or hidden) preference values can be very useful. But how do you find out the name of the preference you need to check, and in which domain (preferences file) you'll find it? Hidden prefs are actually easiiest, because the command you use to write them tells you both the preference name and its location. For the hidden files in Finder tip, for instance, the command is this:
defaults write com.apple.Finder AppleShowAllFiles YES
So to check that in a script, I just need to save the results of defaults read com.apple.Finder AppleShowAllFiles into a variable, and I can then take action based on the variable's value. But what about a normal pref, in an application (or in System Preferences)? Say you wanted to check whether Apple's Pages app was set to show its rulers in inches or centimeters…
Why would you want to know this setting? I don't know, I was just trying to come up with an example. Just go with it…
How do you find out the key name associated with that particular preference, and what file it's stored in? I use a couple of different methods.
Before sandboxing and binary plist files, this was a pretty easy thing to discover: All prefs were written into files named like com.somecompany.someapp.plist in your user's Library > Preferences folder. Change a setting, open the app's preferences file in a text editor, and search for likely candidates. But now, with sandboxing and binary prefs files, sometimes things are't so clear.
Try the easy way
When I'm digging for a pref value and file, I typically try the easy route first: I launch the app in question, then open Terminal. In Terminal, I cd into my user's Library/Preferences folder, and run this command:
ls -alt | more
This lists all files, with the most-recently-changed at the top. Now I make a change in the app (ruler to Centimeters in this example), then quit the app (to hopefully cause the changed pref to be written to disk).
Repeat the ls -alt command, and see if there's a new relevant file near the top of the list. If there is, open it with BBEdit or any other text editor that can read binary plist files. Now use the search feature in the browser, and hopefully find the pref you set by searching for something that might be in its name (Ruler, perhaps, in this example).
In the case of Pages—and many other apps—this won't work in the Preferences folder, because these apps are sandboxed. You'll find Pages' prefererences in your user's Library > Containers folder, then deeply buried in the com.apple.iWork.Pages > Data > Library > Preferences folder, in a file named com.apple.iWork.Pages.plist. This file is the domain you need for the defaults read command—strip off the trailing .plist, though. (Other sandboxed apps will have similar structures for their containers.)
But what about the name of the pref itself, now that you know where it lives? If you open the Pages' preferences file in BBEdit and search on Ruler, the preference is pretty easy to spot:
I closed the prefs file, launched Pages again, and switched back to Points in Pages' prefs. When I checked the prefs file again, the value for RulerUnits was 2. I now know what I need to know for use in a script—a value of 1 indicates centimeters, and 2 means points. You can set this value in a shell script by saving it into a variable via backticks:
pagesUnits=`defaults read com.apple.iWorks.Pages RulerUnits` echo "RulerUnits value is: "$pagesUnits
So much for the easy case. What happens if the prefs are buried somewhere and you just can't find them. Or you find them, but the actual value eludes detection due to strange naming? Then you can try the hard way…
The hard way
To find a preferences file that seems to defy discovery, you can use macOS' ability to track changed files to narrow in on your suspect. Here's how…
- Launch the app in question, and open its prefs, but don't change anything yet.
- In Terminal, change to your user's Desktop with cd ~/Desktop.
- In Terminal, create a root session with sudo -s.
- Create a baseline timestamped file with touch timecheck. This creates an empty file, timestamped at the time you created it.
- As quickly as possible, switch to the app in question, change the preference, quit the app, and switch back to Terminal.
- Enter this command: find -x / -newer timecheck > whatsnew.txt
That last step may take a bit of time, as what it's doing is scanning the filesystem for any files newer than that timestamp on your timecheck file. When it's done, type exit to get out of the root shell, then open the whatsnew.txt file in a text editor. There will probably be a ton of output, because macOS is constantly writing to many files. Use the search feature to search for the app's name, and hopefully you'll find it. For most app-based preferences, you will.
For System Preferences values, you'll find them in your user's Library > Preferences folder, in a file named .GlobalPreferences.plist. You can read this file with defaults read .GlobalPreferences, and it can be opened in BBEdit if you want to search for a setting.
Once you have the name of the file where the pref was written, you can open it in a text editor and try searching. But what if you still can't find the value? In that case, you'll have do one more thing: Compare the prefs file before and after changing the setting; here's how I do that. Note that this assumes the app is in its "unchanged" state when you begin.
- Open the app's settings file in BBEdit. Select all, copy, and then paste into a new document and save it (before.txt). Close the settings file when done.
- Open the app in question, and open its prefs within the app.
- Make your prefs change, then quit the app.
- Open the prefs file again in BBEdit, select all, copy, and paste into a new document. Save this one as after.txt.
- Using BBEdit's Search > Find Differences feature, compare the two files. BBEdit will highlight the lines that have changed, and you should be able to spot the difficult pref.
If anyone knows a surefire easier way to find both the prefs file and the modified value within that file, please do let me know!