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


原文链接: http://blog.csdn.net/afatgoat/article/details/4049965

你可能感兴趣的:(Mac OS X: 编辑PList文件的嵌套键值)