labs

Populating Null Keys using OS X’s PlistBuddy

Abstract

Apple OS X’s PlistBuddy is a tool for modifying p-list (i.e. Property List, .plist) files; however, it has difficulty populating null keys (though little difficulty creating them). This blog post describes a method of using PlistBuddy to populate null keys by first creating & populating a placeholder key and then using the copy directive to populate the null key.

Creating the Null Key is Easy

Creating the null key is easy; use a double-colon (“::”):

/usr/libexec/PlistBuddy -c "add :: dict" /tmp/junk.plist; cat /tmp/junk.plist
File Doesn't Exist, Will Create: /tmp/junk.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key></key>
  <dict/>
</dict>
</plist>

Populating the Null Key: the Right Way

Populate the null key by first creating a placeholder key, populating that, and then copying it to the null key:


rm /tmp/junk.plist
/usr/libexec/PlistBuddy -c "add :placeholder dict" /tmp/junk.plist
/usr/libexec/PlistBuddy -c "add :placeholder:nullKeySubKey string 'hello'" /tmp/junk.plist
/usr/libexec/PlistBuddy -c "copy :placeholder ::" /tmp/junk.plist
/usr/libexec/PlistBuddy -c "delete :placeholder" /tmp/junk.plist
cat /tmp/junk.plist
....
<dict>
  <key></key>
  <dict>
    <key>nullKeySubKey</key>
    <string>hello</string>
  </dict>
</dict>
...

Things that Should Work but Don’t

In general, PlistBuddy will concatenate a double-colon (“::”) into one (“:”). So the key ::nullKeySubKey is treated as :nullKeySubKey, i.e.
/usr/libexec/PlistBuddy -c "add /usr/libexec/PlistBuddy -c "add ::nullKeySubKey string 'hello'" /tmp/junk.plist will not create a null key.

Attempts to trick PlistBuddy with an empty string (e.g. “”) won’t work, either. /usr/libexec/PlistBuddy -c "add :'':nullKeySubKey string 'hello'" /tmp/junk.plist will not create a null key.

Real World Example of Null Keys

The ~/Library/Preferences/com.apple.desktop.plist is a typical p-list file that contains a null key. First, we’ll convert the p-list from binary to XML using plutil, and then we’ll examine the XML to confirm that there is a null key:

plutil -convert xml1 ~/Library/Preferences/com.apple.desktop.plist
less ~/Library/Preferences/com.apple.desktop.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Background</key>
  <dict>
    <key>spaces</key>
    <dict>
      <key></key>
...