Skip to content

Software Engineer at Heydoc

Change macOS user preferences via command line

The System Preferences window is not the only way to adjust user settings. Macs come with a defaults command line interface that lets you read, write, and delete macOS user defaults. You may have even used it before — revealing hidden files in Finder is a popular snippet (hot tip: + + . is quicker).

defaults write com.apple.finder AppleShowAllFiles -string YES

Let’s take it apart to get familiar with the terminology used throughout this article:

  • defaults - interface
  • write - method
  • comapple.finder - domain
  • AppleShowAllFiles - key
  • -string - type descriptor
  • YES - new value

You may be scratching your head asking yourself — why the hell would I prefer to do it through the command line instead of using a nice looking GUI (graphical user interface) to change things? Two reasons! A command line way gives you access to things that you cannot change via graphical panels (toggling hidden files is a perfect example). The next one is even better — do you remember last time when you had to set up a new computer from scratch? Change the settings, add a desktop background, disable the screen saver, download your favourite software etc. How long do you spend on these tasks? Two hours? Four? Ten? I spent about five minutes. Boom!

Write, read and delete defaults settings #

The defaults interface isn’t complicated to use and comes equipped with just a few methods:

  • read - prints current user settings
  • read-type - prints the type of given key
  • write - writes new settings
  • delete - deletes a key or a full domain
  • domains - prints the full list of domains
  • find - searches all domain and keys for a given name
  • help - I’m sure you know what this does

Domains — system components and installed apps #

Printing all the domains via defaults domains is a very helpful way to check what actually can be changed. Domains are objects that contain settings for a particular system component, installed application or a configuration .plist file located in /Library/Preferences/.

defaults domains
...com.apple.ActivityMonitor, com.apple.AddressBook, com.apple.Console, com.apple.DiskUtility, com.apple.FontBook, com.apple.Image_Capture, com.apple.Maps, com.apple.Messages, com.apple.Notes...

Making the output of domains a little bit cleaner #

If you (like me) are not a big fan of the comma separated output of defaults domains, you can pipe it through a translate command to make the output much easier to read.

defaults domains | tr ',' '\n'
...
com.apple.ActivityMonitor
com.apple.AddressBook
com.apple.Console
com.apple.DiskUtility
com.apple.FontBook
com.apple.Image_Capture
com.apple.Maps
com.apple.Messages
com.apple.Notes
...

A basic workflow to amend user defaults #

The idea is to traverse through any domains that we would like to change and compose a command that overrides the current setting. Let’s say we would like to find the command to change spell checking inside the Notes app. The workflow would look something like this:

  1. Print the settings for the notes app to find the right key.
  2. Check the value type for a given key.
  3. Write new settings.
defaults read com.apple.Notes
defaults read-type com.apple.Notes NotesContinuousSpellCheckingEnabled
defaults write com.apple.Notes NotesContinuousSpellCheckingEnabled -bool true

As you can see it is not that complicated. Bear in mind that some changes require you to restart an app or, occasionally, a full reboot of the operating system. A good idea is to close an app before changing any of its settings via the command line.

The way to find the domain & key responsible for a setting #

Browsing through the output of a defaults read command or browsing uncle Google for the correct domain and key can be a daunting task. Luckily you can easily find it out by yourself. Good old diff to the rescue!

  1. Save a state before a change.
  2. Make a change through GUI.
  3. Save a state after a change.
  4. Find the difference.
defaults read > before
defaults read > after
diff before after

Reading output of the default diff command isn’t exactly enjoyable so feel free to use any other diff tool. Time for a hot tip now! Visual Studio Code, apart from being really cool code editor, is a fantastic diff tool. Just have a look!

code --diff before after

Visual Studio Code as a diff tool

My defaults tweaks #

I actively maintain a list of settings that I change on my machine and you can find it on my dotfiles repository on Github. It isn’t too complex so if you are looking for a real ninja-level defaults tweaks example look at Mathias Bynens one.

Hopefully this article helped you to embrace the power of the defaults command. Share in the comments below your favourite defaults tweaks and stay tuned as more tutorial articles like this one are coming soon. Until next time.

Comments

  • D
    David Turner

    Excellent post - just what I was after. You, sir, are a steely-eyed missile man......

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Thanks a lot for reading. Have a great day :)

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • M
    Max Bigras

    Have you tried wrangling the modifier keys using this technique?

    For example, mapping the caps lock to control, using the diff method, I'm not able to interpret the results:

     
    diff before after
    19582c19582
    < Age = "28961.18159047101";
    ---
    > Age = "30450.340939837";
    19686a19687,19689
    > 1437,
    > 1453,
    > 1452,
    21316c21319
    < "NSWindow Frame Main Window Frame SystemPreferencesApp 8.0" = "345 195 668 448 0 0 1280 800 ";
    ---
    > "NSWindow Frame Main Window Frame SystemPreferencesApp 8.0" = "345 100 668 543 0 0 1280 800 ";

    https://uploads.disquscdn.c...

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Sorry but I don't have any experience with things like that. Interesting use case though.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
    • P
      Piotr Trzeciak

      You can use Karabiner Elements to do this

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • G
    Gandalf Saxe

    Is it possible to set notification settings for apps using the command line?

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • G
      Gandalf Saxe

      Aww yes this looks like the one: https://github.com/jacobsal... - however it doesn't support latest macOS, so I'm holding out for that.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
      • Pawel Grzybek
        Pawel Grzybek

        Sorry, I am helpless here :( I have no experience with that.

        👆 you can use Markdown here

        Your comment is awaiting moderation. Thanks!
  • T
    Tim

    Thanks for the post! I'm automating my Mac setup and this is exactly what I wanted.

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • J
    Janek

    hey, that was awesome, thank you so much!
    you might consider changing your first example, that exact key seems not to exist anymore in 10.14.1, unless I'm confused or wrong

    and another benefit of changing this from shell you might want to put there is that you can put it in a script that needs a certain setting to work correctly

    [I came searching for this for my alarm clock setup that needs the Power -> Schedule setting]

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Very good spot with this first example. Personally I always use keyboard shortcut so I haven't even noticed.

      Thanks for reading and great suggestions.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • J
    Jordan Davis

    Hi can you change a privacy setting in System Preferences using Terminal?

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • l
    lucky zhou

    Hi, thanks for you sharing, I got a setting like this:

    {
    "test1"=1;
    "test2" = (
    "prop"=1;
    "prop2"=2;
    )
    }

    How to update prop2?

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      I am more than happy to help you with this one but you need to provide a full domain command that you have used to read this value. It should not be difficult, but I need some more context.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
      • l
        lucky zhou

        thanks for your reply, actually, I used font-icons in my terminal, so I should to set the correct font for terminal, like iTerm2, it can be configured in preference manually, but after I get its domain info, I found the setting item is in an object-array like "New Bookmarks"=( { font="xxx"; other="ssxx" }, { etc... } ); there are so many settings in every object, so now no matter use array or array-add are not easy to do it.

        👆 you can use Markdown here

        Your comment is awaiting moderation. Thanks!
  • E
    Entreprenerd

    Great write up... I have struggled with this on numerous attempts and this time I hit 3 websites, each better than the last and this was the last. Thanks for sharing!!

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Thanks a lot for a kind word. I am glad it helped you out.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • M
    Marcel

    Hey, I tried your diffing technique when changing certain shortcut settings. However, the diff only shows 'enabled = 1' to 'enabled = 0'. It doesn't show which setting is changed, is there any way to check which one it is? The settings I'm trying to change is Keyboard > Shortcuts > Accessibility > Turn VoiceOver on or off.

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Yeah, I know it is not the best user experience. I tend to use some diff tool — Visual Studio Code has one built-in that works like a charm for me. You need to climb up the tree and check which flag has been changed.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • J
    John Welbourn-Smith

    Nice article Pawel. 👍 I was looking for some commands to set Macs up remotely and this looks like it will do the trick nicely. I particularly like the diff tip, that’s a handy way to find obscure settings. 😃

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!

Leave a comment

👆 you can use Markdown here

Your comment is awaiting moderation. Thanks!