Tracking where settings are stored on macOS Jun 28 2019
In this post, I’ll explain how to figure out where macOS stores specific preferences and how to modify them using the command line tool
defaults. Knowing where the preferences are stored and how to manage them programmatically allows us to create scripts that will help us automate the setup of one or many computers. I think you’ll find it useful.
I was sharing some code through Slack when I noticed that all my straight quotes (
') were replaced by smart quotes (’). I felt cheated, I remember this happening in other apps before, but I’ve stopped myself in the past from fixing it because I don’t want to run after any premature-optimization or automation. The simple solution is to go to
Settings > Keyboard > Text and deselect the “Use smart quotes and dashes” checkbox. But how and where do macOS stores user’s preferences?
The macOS defaults system
User preferences are stored in the
defaults system of macOS. The users’ defaults are structured by domains, and each application generally corresponds to one domain. The domain name is typically written in reverse internet domain style, for example, if I had an app called “timer” a likely domain name would be
com.rderik.timer and under that domain, you’ll find a
plist with the user preferences.
A properties file (
plist) contains settings or preferences, these files are in XML format, they follow Apple’s core Foundation DTD. For more Information check Apple’s property list files documentation.
I knew I was looking for one
plist where the defaults were being stored, so I used the command
fs_usage to obtain a list of the file system activity. Using the following command:
1 $ sudo fs_usage -f filesys | grep plist
That will throw lots of lines to your screen, you could redirect it to a file and then study the file for possible candidates or try to be observant and see which file appears every time you change the setting. For me, the one that appeared every time I changed the setting was:
1 0:01:27 lstat64 /Users/rderik/Library/Preferences/.GlobalPreferences.plist
Most of the time the defaults would be located in the following directories:
1 2 3 4 5 ~/Library/Preferences/com.domain.app.plist ~/Library/SyncedPreferences/com.domain.app.plist # If the app is sandboxed ~/Library/Containers/com.domain.app/Data/Library/Preferences/com.domain.app.plist ~/Library/Containers/com.domain.app/Data/Library/SyncedPreferences/com.domain.app.plist
Now I had the
plist file, I only needed to check the value I need to modify. But how do we edit a
plist file? We could simply use any editor and open it (
vim for example), but that is error prone and not recommended. You could use the command
plist, and that would be correct if we were editing any
plist file, but this time we are going to use the
defaults command to interact with the defaults file.
First, we are going to read the whole domain and see what is stored there:
1 $ defaults read ~/Library/Preferences/.GlobalPreferences.plist
And you should have obtained a list of all your preferences, I found two promising variables:
1 2 NSAutomaticDashSubstitutionEnabled = 1; NSAutomaticQuoteSubstitutionEnabled = 1;
Every time I switched the preference, these two values changed, the name has given them away, but I wanted to be sure. Now we can use the
defaults command to modify them instead of clicking on System Preferences. Let’s use the following commands:
1 2 $ defaults write ~/Library/Preferences/.GlobalPreferences.plist NSAutomaticDashSubstitutionEnabled -bool false $ defaults write ~/Library/Preferences/.GlobalPreferences.plist NSAutomaticQuoteSubstitutionEnabled -bool false
And now I tried again to use straight quotes (‘) on Slack, and it worked! No automatic change.
What have we learned?
We learned that we can use
fs_usage to listen for system calls and filesystem activity, this can be helpful to find other configurations written by any other programs and information on what system calls are being triggered. I would recommend having a look at the
man page for the
fs_usage command. Also, we saw how using the
defaults command we have access to settings that might not be available on a graphical interface, again I would recommend checking the
man page for more information.
We accessed the files directly, but if we know the domain that the application belongs to, we could access it only using the
defaults command. For example, to access any global configuration you’ll normally find them in the
NSGlobalDomain domain, so instead of going directly to the file we could have used the following command and obtain the same result:
1 $ defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false
defaults command gives us access to a lot of information. For example, you can see a list of all the available domains:
1 $ defaults domains
From that list you can explore the ones you find intriguing, you might find some interesting information.
1 $ defaults read NSGlobalDomain
I think you can see how useful this method of setting preferences is, you now can create a script that will have all the preferences you require and use it to set any new computer or maybe if you are in charge of setting up all the machines at work now you have a way to automate it.
I hope this was useful, let me know if you have any questions or comments.
Related topics/notes of interest
- Apple’s Configuration Profile Reference - Describes the payloads for many modules.
I don’t agree but here is an article that gives a case for using smart quotes http://smartquotesforsmartpeople.com/
A nice setup script for setting macOS preferences by Geerlingguy.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # Disable smart quotes defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false # Disable smart dashes defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false # Show hidden files on finder defaults write com.apple.finder AppleShowAllFiles -bool true # Thanks to @geerlingguy for this: # Trackpad: map bottom right corner to right-click defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad TrackpadCornerSecondaryClick -int 2 defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad TrackpadRightClick -bool true defaults -currentHost write NSGlobalDomain com.apple.trackpad.trackpadCornerClickBehavior -int 1 defaults -currentHost write NSGlobalDomain com.apple.trackpad.enableSecondaryClick -bool true # Disable `.DS_Store` files when using Network drives defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true # Don't show the list of users, ask for username and password on the login screen # This doesn't work if you are using FileVault 2, FileVault only allows the list of users # I spent too much time trying to figure it out. It is currently impossible to change it if you # are using FileVault defaults write /Library/Preference/com.apple.loginwindow SHOWFULLNAME -bool true