如何仅从PID获取应用程序的Bundle ID(或plist路径)?

时间:2012-01-12 18:16:45

标签: macos bash shell plist nsuserdefaults

"How to find Bundle Identifier from known PID?""How to read plist information (bundle id) from a shell script类似,但不同......因为这些都与Xcode构建变量扩展等有关。

我的问题是,在BASH shell中,他们只知道值是进程'PID,如何获取该进程' PATH,或唯一的“Bundle ID”。

我确信有一个可怕的正则表达式来解析ps,但我希望有更清洁,更便携的东西。前面提到的帖子中的评论包括

BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "${BUILD_ROOT}/${INFOPLIST_PATH}")

但是,我不认为每台Mac上都安装了plistbuddy,更重要的是,我的问题是在理论脚本中,而不是在Xcode构建阶段。

我已尝试plutilplistkitplistdump,但似乎没有人能够做到这一点。

我尝试实现此目的的原因是能够执行defaults read / write函数而无需对父进程的BundleID进行硬编码。我知道如何将此信息作为参数传递给脚本..但我希望能够怀疑在脚本中检查..

1 个答案:

答案 0 :(得分:1)

无需使用可怕的正则表达式来解析ps的输出 - ps实用程序已经按照您的要求执行了操作。用(通常看起来有些神秘的)以下选项调用它

ps [-ww] -o comm= -p <pid>

将返回属于您的PID的可执行文件的路径(仅当您输出到终端时才需要-ww参数,因为ps将截断没有它的返回路径。它不应该是否则必须)。

从那里检索软件包ID的问题是并非所有进程都映射到带有Info.plist(它定义软件包ID)的软件包 - 特别是,* nix类型的可执行文件不是软件包,因此没有软件包ID。此外,即使在app bundle的情况下,ps也会返回应用程序的核心可执行文件,而不是包本身的路径。由于应用程序包中可执行文件的路径是标准化的(但它位于Path.app/Contents/MacOS),因此可以通过一些目录遍历来检索它。

假设您已将ps调用的输出存储在变量execfile中,此

[[ ${execfile%/*} =~ ^.+/Contents/MacOS$ ]] && defaults read "${execfile%/*/*}"/Info CFBundleIdentifier

将使用defaults检索每个应用程序包在其根目录中包含的CFBundleIdentifier文件的Info.plist键的值,从而检索可能路径的包标识符。