Perl Plist
Perl Plist Script and Examples
This script contains perl code that uses the PerlObjCBridge to read and modify Mac OS X plist format files. Plist files are ubiquitous on Mac OS X. I originally wrote 2 articles about this (article 1 and article 2) and my intention was to use them for personal projects but they have become so critical at work (Mac OS X system administration, I use it in nearly 30 scripts) I think I would feel handicapped if I didn't have them. So I keep improving and working on these scripts. Here is the latest version and some script examples and utilities.
Watch a presentation on this.
If you have questions, don't hesitate to contact me!
Download
- perlplist.pl - The shared library of functions. Save it to "/usr/local/lib". (Version 8.3.16 - Added 2012-10-04)
- plist.pm - Same thing as perlplist.pl but as a Perl Module (made by Sam Forester at utah.edu).
- superDefaults.pl - Very similar to the defaults command, but "super" (lol).
- plcat - This script will print a plist file as xml no matter what the original format is (binary bleck). If you specify 2 plist files it will combine them. Values that differ will not be combined but show an error. Values can only be combined that are missing (dictionary keys or the end of an array). (Added 2011-03-22)
- logger.pl - This script parses the output of /usr/sbin/system_profiler to get things like the mice connected (and a lot of other stuff but I'm including it here for the example of defaultsFromString and pathsThatMatchPartialPathWithGrep. (Added 2012-10-04)
- pldiff - This script will compare 2 plist files and print out differences similarly to the diff command. (Added 2011-03-22)
- set_ip.pl - A script that parses OS X's network pref file and set's the IP of the current location. You can set it to DHCP or manual. You can set router and subnet mask as well. You can also specify an interface (Ethernet (default), Airport, or FireWire). It can also point to any preferences.plist file. It does not activate the settings, it just changes the file. Use ncutil to actually activate the settings. Last updated 2012-10-04 with the ability to use a config file.
- get_ip.pl - A script that parses OS X's network pref file and get's the IP of whatever is set to Manual (presumably Ethernet--yeah, this script is fairly basic).
- FoundationExamples - Here is another script containing all functions, but in object form (sent to me by HB Desiato). This does not have any of the new additions I've created,
Features
Features of the perlplist.pl script.
- Read and write plist files (all objects are original Cocoa objects referenced by a Perl pointer).
- Dig into a plist object and read or write Cocoa values (without converting it to Perl).
- Convert Cocoa objects into Perl versions (NSDictionary to HASH, NSArray to ARRAY, NSData to a base64 string, and all other values into SCALARS.
- Convert Perl objects into Cocoa versions (HASH to NSDictionary, ARRAY to NSArray, a base64 string into NSData, and SCALARS into NSStrings.
- Create Cocoa objects NSDate, NSData, and NSNumber (bool, int, float) from Perl SCALARS.
- Convert a string representation of xml plist to an NSDictionary (which can be saved as plist).
Features added in 8.3.12.
- Updated for 10.7
- More documentation in the script.
- Added pathsThatMatchPartialPathWithGrep, which basically matches plist keys using grep expressions.
Features added in 8.3.13.
- Added cocoaDataFromHex( $hex ) and cocoaDataFromBase64( $base64), which take a hex or base64 string and make an NSData object with it.
- perlValue can now convert (and print) NSData objects.
Features added in 8.3.14.
- Added -ai token for setPlistObjectForce, which inserts an object at an array # index instead or replacing the object
Features added in 8.3.15.
- perlValue now prints NSCFDate as a unix timestamp using timeIntervalSince1970(). Contributed by Adam Reed at anu.edu.au.
Features added in 8.3.16.
- Improved scope with more my's and our.
- Improved regex's for objectType
Known issues.
- When printing an NSString that contains xml entities (e.g. "<" and ">") they will be displayed incorrectly (e.g. "<" and ">").
- I'm very away that converting this to a package would be cool but I've never understood Perl's package system and my motivation to do so isn't very high so I don't think it is going to ever happen.
Features of the script examples.
- Compare 2 plist files (using pldiff script).
- Print binary plist files as xml (using plcat script).
- Combine 2 plist files (using plcat script).
- Set the IP (router and subnet mask) of the active Ethernet, Airport, or FireWire interfaces of any preferences.plist file.
Examples
james% sudo superDefaults.pl /private/var/db/launchd.db/com.apple.launchd/overrides.plist --add -d com.openssh.sshd -d Disabled -b 0
james% sudo superDefaults.pl ~/Library/Preferences/com.apple.Safari.plist --add -d WebKitJavaScriptCanOpenWindowsAutomatically -b 0
james% sudo superDefaults.pl /Library/Preferences/com.apple.AppleFileServer.plist --add -d guestAccess -b 0
james% sudo superDefaults.pl /Library/Preferences/com.apple.Bluetooth.plist --add -d BluetoothAutoSeekHIDDevices -b 0
james% sudo superDefaults.pl /Library/Preferences/DirectoryService/DSLDAPv3PlugInConfig.plist --add -d "LDAP Server Configs" -a 0 -d "Record Type Map" -a 0 -d "Attribute Type Map" -a 4 -d "Native Map" -a 0 -s "#/Users/kiosk"
james% sudo superDefaults.pl /etc/authorization --add -d rights -d system.privilege.taskport.debug -d class -s allow
james% sudo superDefaults.pl /Library/Preferences/.GlobalPreferences.plist --add -d "com.apple.ColorSync.Devices" -d "Device.mntr.756E6B6E-0000-0717-0000-00005B81C5C0" -d "CustomProfiles" -d "1" -s "/Library/ColorSync/Profiles/Projector Profile.icc"
james% plcat test1.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>3</key>
<array>
<string>1</string>
</array>
<key>1</key>
<string>A</string>
<key>2</key>
<dict>
<key>2</key>
<string>B</string>
</dict>
</dict>
</plist>
james% plcat test2.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>3</key>
<array>
<string>1</string>
<string>2</string>
</array>
<key>2</key>
<dict>
<key>1</key>
<string>A</string>
</dict>
</dict>
</plist>
james% pldiff test1.plist test2.plist
> /{3}/[1]/2
< /{1}/A
< /{2}/{2}/B
> /{2}/{1}/A
james% plcat test1.plist test2.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>3</key>
<array>
<string>1</string>
<string>2</string>
</array>
<key>1</key>
<string>A</string>
<key>2</key>
<dict>
<key>1</key>
<string>A</string>
<key>2</key>
<string>B</string>
</dict>
</dict>
</plist>
Python
Philip Rinehart at Yale loves Python. He sent me this Python version of get_ip (it doesn't read binary plists afaik, but you can install and include pyobc to get around this, or you can run plutil -convert xml1 on the file first...). This is a lot cleaner than the perlplist examples.
- get_ip.py - A script that parses OS X's network pref file and get's the IP of the current location.
Comments
I'm not a traditional website guy and so I don't have comment fields. If you would like to leave a comment, email me and I'd be happy to add them to this page.