git 我怎么能在OS X上解析`defaults read`的输出?

ulydmbyx  于 2023-05-27  发布在  Git
关注(0)|答案(6)|浏览(162)

如何解析OS X defaults read终端命令的输出?
它似乎输出“旧”NeXTSTEP plist格式;看起来像这样:

{
"Apple Global Domain" =     {
    AppleAntiAliasingThreshold = 4;
    AppleCollationOrder = root;

我尝试将输出写入文件并使用plutil进行转换,但它阻塞了:

> defaults read > defaults.txt
> plutil -convert xml1 defaults.txt
2014-02-02 21:29:14.856 plutil[56896:707] CFPropertyListCreateFromXMLData(): Old-style
plist parser: missing semicolon in dictionary on line 10835. Parsing will be abandoned.
Break on _CFPropertyListMissingSemicolon to debug.
defaults.txt: Property List error: Unexpected character { at line 1 / JSON error: No
value for key in object around character 28.

你问为什么?
我想在git中存储默认值,这样我就可以在应用更改后保留更改设置和差异的记录,但似乎defaults read中的序列化不是'行顺序稳定':字典不会以一致的顺序转储它们的键,从而导致大量的噪声。如果我可以解析defaults read,那么我就可以通过顺序一致的串行化器将数据输出。

xxls0lw8

xxls0lw81#

plutil可以转换为xml或json

#!/bin/bash
f='~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure'
x="$(plutil -convert xml1 -o - "$f")"
j="$(plutil -convert json -o - "$f")"

-o -表示:将结果打印到标准输出
$f是plist格式的输入文件

yqkkidmi

yqkkidmi2#

你是个幸运的家伙,就在几天前,有人在PyPi上发布了一个NeXTSTEP plist格式的解析器-nsplist

y53ybaqx

y53ybaqx3#

所有这些评论都试图有所帮助,但似乎来自那些没有真正尝试在最近(至少是2014年后)的macOS上处理defaults read输出的人。
输出不是有效的JSON或旧式的几乎是JSON NS。很近了。它不能被任何建议的答案解析。
这是令人沮丧的,在macOS开发世界中并不罕见。

j0pj023g

j0pj023g4#

这里有一个脚本(使用Swift)直接读取默认值,而不是解析默认值命令的输出:

#!/usr/bin/swift

// Usage:
// dread com.apple.dt.Xcode IDEApplicationwideBuildSettings   
// dread com.apple.dt.Xcode IDEApplicationwideBuildSettings.SYMROOT
// Example:
//         $ dread com.apple.Terminal "Default Window Settings"
// returns $ Basic

import Foundation

var args = CommandLine.arguments
args.removeFirst()
if let suite = args.first, let defaults = UserDefaults(suiteName: suite) {
    args.removeFirst()
    if let keyPath = args.first, let value = defaults.value(forKeyPath: keyPath) {
        print(value)
    } else {
        print(defaults.dictionaryRepresentation())
    }
}

如果将其保存为名为dreadchmod +x dread的文件,则可以读取应用程序的默认值并将其打印出来,如下所示:
dread com.apple.dt.Xcode IDEApplicationwideBuildSettings
因为这是一个字典,你可以使用以下命令从字典中读取一个键:
dread com.apple.dt.Xcode IDEApplicationwideBuildSettings.SYMROOT
等等。

zd287kbt

zd287kbt5#

请原谅我回答一个与你的问题相近的问题。
您可以看到,defaults命令行工具在默认情况下发出内容层次结构的字符串表示,称为[NSObject description],这是一种不正式的格式,没有完整的文档记录,并且不能依赖。如果在任何日志行中发出NSObject派生,则可以看到以下格式:

NSLog(@"This is the string representation of a dictionary: %@", myDictionary);

或者在Xcode调试器(LLDB)中:

po myDictionary

当然,当你从shell使用' defaults read '命令时。这种格式不意味着要被解析,并且可能丢失信息,并且不被认为是打印对象的任何适当的“序列化”。
然而,正因为如此,defaults命令提供了export子命令,作为read的替代。
令人沮丧的是,这个子命令在man defaults中没有记录,只是偶然我在defaults helpdefaults -h中发现了它。以下是相关摘录:

export <domain> <path to plist>      saves domain as a binary plist to path
  export <domain> -                    writes domain as an xml plist to stdout

这些输出,无论是在磁盘文件上还是作为xml打印到标准输出,都可以使用正常可可机制(Foundation集合初始化器,从文件或数据,NSPropertyListSerialization协议等)安全轻松地解析。例如,如果将第二个变量的stdout收集到NSData对象中,则解析它将如下所示:

NSData *outputOfDefaultsCommand;
NSError *error;
NSPropertyListFormat format;
NSDictionary *dict = [NSPropertyListSerialization propertyListWithData: outputOfDefaultsCommand options:NSPropertyListImmutable format:&format error:&error];
if ( !dict || error)
    NSLog(@"Failed to read NSDictionary from .plist data output of 'defaults' command. Error:%@", error);
else 
    NSLog(@"Parsed 'defaults' output: %@", dict);
esyap4oy

esyap4oy6#

你试过defaults export吗?这将输出一个二进制文件,然后可以使用plutil将该文件转换为.plist

相关问题