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?
Table of Contents
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.
What are plist
files?
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.
Using defaults
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
The 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
Final thoughts
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.
Interesting settings:
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