Plist文件是以.plist为结尾的文件的总称. 众所周知, Plist在Mac OS X系统中起着举足轻重的作用,就如同Windows里面的Registry一样,系统和程序使用Plist文件来存储自己的安装/配置/属性等信息。正如 可以使用命令行命令来处理大多数系统管理一样,操作Plist文件也是系统提供的。
本文介绍Defaults, PlistBuddy和Plutil命令的功能使用,并介绍了一些基本的概念,比较了命令之间的异同,着重解决嵌套键值的操作,并根据不同情况使用两种方式实现。通过实际例子给出步骤和结果的做法贯穿本文始终。
对于Mac OS X系统自带的Defaults命令来说, 能提供有限的对Plist文件的操作,一般来说,对于根键值的操作可以很容易的操作, 但是对于复杂嵌套的键值来说,Defaults命令就力不从心了.
比如,对于下面的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>Software</key> <dict> <key>Gallery</key> <dict> <key>OnlineMarketplace</key> <string>http://www.market.com/default.aspx</string> </dict> </dict> </dict> </plist> |
使用Defaults命令很容易在根,和Software并列处添加一个键值比如:Version="1.0"
在命令行里Defaults命令显示的原来的plist文件是这个样子的:
$ defaults read ~/Desktop/com.sample { Software = { Gallery = { OnlineMarketplace = "http://www.market.com/default.aspx"; }; }; } |
添加完键值后,是:
$ defaults write ~/Desktop/com.sample Version "1.0" $ $ defaults read ~/Desktop/com.sample { Software = { Gallery = { OnlineMarketplace = "http://www.market.com/default.aspx"; }; }; Version = "1.0"; } |
但是如果在Software下面的Gallery下面添加一个键值就很困难。而多层嵌套的Plist键值是随处可见的, 所以找到一种方法方便于操作Plist的嵌套键值很必要. 当然了,这里限于命令行方式,开发工具提供了一整套的API函数操作,这里不涉及。
注:具体的defaults命令的使用参考man文档.
所幸有PlistBuddy工具,这个工具通过它的简单语法就可以操作嵌套的键值.
而PlistBuddy工具,不象Defaults命令是随系统安装的,不是随着OS X系统自动安装的,其实有好多个Apple的程序包括了这个工具,可以使用下面的命令来检查是否已经安装了:
$ find /Library/Receipts -name *PlistBuddy /Library/Receipts/iTunesX.pkg/Contents/Resources/PlistBuddy /Library/Receipts/RemoteDesktopAdmin322.pkg/Contents/Resources/PlistBuddy /Library/Receipts/RemoteDesktopRMDB.pkg/Contents/Resources/PlistBuddy |
上面是我的系统里面安装PlistBuddy的所有安装包的列表。在我的机器上PlistBuddy安装在:
$ whereis plistbuddy /usr/bin/plistbuddy |
而其实那是它的一个link,真正的文件在/usr/libexec/PlistBuddy
如果你的系统没有PlistBudy可以安装苹果的开发工具.
基本的使用可以查看man文档或者是在线帮助:
$ plistbuddy -h Command Format: Help - Prints this information Exit - Exits the program, changes are not saved to the file Save - Saves the current changes to the file Revert - Reloads the last saved version of the file Clear [<Type>] - Clears out all existing entries, and creates root of Type Print [<Entry>] - Prints value of Entry. Otherwise, prints file Set <Entry> <Value> - Sets the value at Entry to Value Add <Entry> <Type> [<Value>] - Adds Entry to the plist, with value Value Copy <EntrySrc> <EntryDst> - Copies the EntrySrc property to EntryDst Delete <Entry> - Deletes Entry from the plist Merge <file.plist> [<Entry>] - Adds the contents of file.plist to Entry Import <Entry> <file> - Creates or sets Entry the contents of file Entry Format: Entries consist of property key names delimited by colons. Array items are specified by a zero-based integer index. Examples: :CFBundleShortVersionString :CFBundleDocumentTypes:2:CFBundleTypeExtensions Types: string array dict bool real integer date data Examples: Set :CFBundleIdentifier com.apple.plistbuddy Sets the CFBundleIdentifier property to com.apple.plistbuddy Add :CFBundleGetInfoString string "App version 1.0.1" Adds the CFBundleGetInfoString property to the plist Add :CFBundleDocumentTypes: dict Adds a new item of type dict to the CFBundleDocumentTypes array Add :CFBundleDocumentTypes:0 dict Adds the new item to the beginning of the array Delete :CFBundleDocumentTypes:0 dict Deletes the FIRST item in the array Delete :CFBundleDocumentTypes Deletes the ENTIRE CFBundleDocumentTypes array |
这里主要解释一下PlistBuddy的几个关键点.
比如:
$ plistbuddy -c "Print Software" ~/Desktop/com.sample.plist Dict { Gallery = Dict { OnlineMarketplace = http://www.market.com/default.aspx } } |
注意两点:
可以有两种方式,实现对嵌套键值的操作。下面主要通过添加键值来说明具体的操作.
$ plistbuddy -c 'Add :Software:Gallery:Version string "1.0"' ~/Desktop/com.sample.plist $ plistbuddy -c "Print" ~/Desktop/com.sample.plist Dict { Software = Dict { Gallery = Dict { OnlineMarketplace = http://www.market.com/default.aspx Version = 1.0 } } } |
<?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>Global Gallery</key> <dict> <key>AppPath</key> <string>/Applications/Gallery/Gallery Setup</string> <key>Arguments</key> <string>-configuration "-c"</string> <key>Enabled</key> <integer>1</integer> </dict> </dict> </plist> |
$ plistbuddy -c "Merge ~/Desktop/Global.plist :Software:Gallery" ~/Desktop/com.sample.plist $ plistbuddy -c "Print" ~/Desktop/com.sample.plist Dict { Software = Dict { Gallery = Dict { OnlineMarketplace = http://www.market.com/default.aspx Version = 1.0 Global Gallery = Dict { AppPath = /Applications/Gallery/Gallery Setup Enabled = 1 Arguments = -configuration "-c" } } } } |
在Mac OS X 10.5之前的系统里面,使用defaults命令操作完Plist文件后,Defaults命令并不改变原来的Plist文件的编码方式,OS X支持两种编码:文本的XML方式和二进制方式. 对于二进制方式,用户无法使用文本编辑或者如cat命令等来显示该文件, 这对于用户来说不方便,但是系统可以更快地处理二进制的Plist文件,可能基于这个原因,Leopard改变了Defaults的行 为:Defaults命令会改变Plist文件为二进制格式。
Plutil是开发环境提供的一个命令行命令,使用这个命令可以转换Plist文件的格式,而且可以检查Plist文件的语法和完整性.
$ plutil -convert xml1 ~/Library/Preferences/com.apple.help.plist |
上面的命令将~/Library/Preferences/com.apple.help.plist文件的格式转化为文本XML格式
$ plutil -lint ~/Library/Preferences/com.apple.help.plist |
上面的命令检查~/Library/Preferences/com.apple.help.plist文件, 正确返回:OK.
Wikipidia上的关于操作Plist的说明也是很好的文档:Manipulating Plists
Entry, Key: 键值
Nested Key: 嵌套键值