Mac OS X: 编辑PList文件的嵌套键值

Mac OS X: 编辑PList文件的嵌套键值

前言

Plist文件是以.plist为结尾的文件的总称. 众所周知, Plist在Mac OS X系统中起着举足轻重的作用,就如同Windows里面的Registry一样,系统和程序使用Plist文件来存储自己的安装/配置/属性等信息。正如 可以使用命令行命令来处理大多数系统管理一样,操作Plist文件也是系统提供的。

本文介绍Defaults, PlistBuddy和Plutil命令的功能使用,并介绍了一些基本的概念,比较了命令之间的异同,着重解决嵌套键值的操作,并根据不同情况使用两种方式实现。通过实际例子给出步骤和结果的做法贯穿本文始终。

:Defaults:

对于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工具,这个工具通过它的简单语法就可以操作嵌套的键值.

而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的几个关键点.

  • 如何定义嵌套的键值: 正如前面说的它使用一种简单的描述方式,上一层的键值在前面,而每个键值之间使用":"符号分隔, 比如:本文最初的例子中Software->Gallery->OnlineMarketplace表述 为:":Software:Gallery:OnlineMarketplace", 第一个":"表示根.
  • 而如果键值的名称包含空格等特殊字符的时候,如同命令行的转义字符一样,使用"/"来转义,比如: ":Software:Gallery:Online/ Marketplace".
  • PlistBuddy如果不使用"-c"参数,则进入人机交互模式, "-c"的意思就是执行它后面的命令列表,而命令如果有参数,需要把它们包含在引号中,


比如:

$ plistbuddy -c "Print Software" ~/Desktop/com.sample.plist
Dict {
Gallery = Dict {
OnlineMarketplace = http://www.market.com/default.aspx
}

}

注意两点:

  1. PlistBuddy后面的Plist文件应该是文件的全名,而Defaults需要把.plist的文件后缀祛除。
  2. PlistBuddy和Defaults的输出是不一样的.

操作嵌套的键值:

可以有两种方式,实现对嵌套键值的操作。下面主要通过添加键值来说明具体的操作.

  • 如果只是添加一个单一属性键值,比如是string/integer/bool/date等类型的,那么可以直接使用add命令来添加. 比如我们希望在Software->Gallery键值下面添加一个Version的字符串类型的键值, 值是"1.0", 那么使用先面的命令
$ 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
}
}
}

看到了,很简单吧。

  • 当添加的键值是一个dict/arry/data等复杂类型,而且里面又包含了好多子键值,为每一个子键值写一句命令,很是费时间和空间,不 如使用第二个方法,首先使用文本编辑器或者Plist Editor,把需要的键值编辑成一个单独的plist文件,使用PlistBuddy的合并"Merget"命令来添加到目标Plist文件,只使用一 条命令就可以解决问题.

比如我现在希望将下面的键值导入到前面的com.sample.plist文件的Software->Gallery中, 参见下面的命令:

<?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>

上面是要被添加的复杂键值文件叫做Global.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"
}
}
}
}

从上面运行的结果看很是方便简洁。

XML和二进制文件:

在Mac OS X 10.5之前的系统里面,使用defaults命令操作完Plist文件后,Defaults命令并不改变原来的Plist文件的编码方式,OS X支持两种编码:文本的XML方式和二进制方式. 对于二进制方式,用户无法使用文本编辑或者如cat命令等来显示该文件, 这对于用户来说不方便,但是系统可以更快地处理二进制的Plist文件,可能基于这个原因,Leopard改变了Defaults的行 为:Defaults命令会改变Plist文件为二进制格式。

:Plutil:

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: 嵌套键值

你可能感兴趣的:(Mac OS X)