4

我希望能够确定从 Finder 在命令行的角度来看,诸如“.app”之类的目录是否被视为一个包或捆绑包。我认为用一个小的 shell 程序来做这件事并不难,但如果我不需要的话,我宁愿不重新发明轮子。

4

6 回答 6

8

这有点晚了,但是:您似乎可以使用 mdls 命令检测捆绑包。具体来说,(多行)输出:

mdls -name kMDItemContentTypeTree /Path/To/Directory

将包含字符串

"com.apple.package"

(包括引号,至少从 Lion 开始)如果目录是一个包。如果包也是一个包,输出也将包含

"com.apple.bundle"

最后但并非最不重要的一点是,如果它专门是一个应用程序包,则输出还将包含

"com.apple.application-bundle"

(这是根据一些非常有限的测试,但从 Apple 关于统一类型标识符的文档和 mdls 的手册页来看,这应该是正确的。对于我测试的项目,对于非 Apple 提供的捆绑包也是如此,考虑到尿路感染的目的,这是您所期望的。)

于 2012-09-02T06:00:49.890 回答
4

虽然您可以根据“./contents/Info.plist”的存在来识别某些包,但并非所有包类型(例如文档和旧包)都需要它。Finder 还根据文件扩展名将目录识别为包(.app、.bundle 等)或者如果设置了捆绑位。

要从命令行检查捆绑位,请使用:

getFileInfo -aB directory_name

为了抓住所有情况,我会检查:

  • 捆绑位设置了吗?
  • 如果没有,它是否具有将其标识为捆绑包的文件扩展名?(见Mecki 的回答
  • 如果不是,它可能不是一个捆绑包。
于 2008-09-23T15:24:15.707 回答
4

更新:

在所有具有 Spotlight 的系统上,使用mdls您可以检测查看 kMDItemContentTypeTree 属性的包。例如:

mdls -name kMDItemContentTypeTree "/Applications/Safari.app"

为我产生以下输出

kMDItemContentTypeTree = (
    "com.apple.application-bundle",
    "com.apple.application",
    "public.executable",
    "com.apple.localizable-name-bundle",
    "com.apple.bundle",
    "public.directory",
    "public.item",
    "com.apple.package"
)

每当你看到com.apple.package那里时,它应该被 Finder 显示为一个包。当然,名称中带有“bundle”的所有内容都暗示已经但并非所有包都是捆绑包(捆绑包是具有明确定义的目录结构的包的特定子集)。


老答案:

您可以使用以下命令(Leopard 之前的 OS X)获取所有已注册文件类型扩展名的列表:

/System/Library/Frameworks/ApplicationServices.framework/Frameworks\
/LaunchServices.framework/Support/lsregister -dump

或对于 Leopard 及更高版本:

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks\
/LaunchServices.framework/Versions/A/Support/lsregister -dump

那里的每个文件扩展名都有标志。如果设置了包标志,则这是一个包。

例如

  claim   id:            806354944
            name:          Bundle
            role:          none
            flags:         apple-internal  relative-icon-path  package  
            icon:          Contents/Resources/KEXT.icns
            bindings:      .bundle
    --------------------------------------------------------
    claim   id:            1276116992
            name:          Plug-in
            role:          none
            flags:         apple-internal  relative-icon-path  package  
            icon:          Contents/Resources/KEXT.icns
            bindings:      .plugin

将此与没有捆绑的文件进行比较

    claim   id:            2484731904
            name:          TEXT
            role:          viewer
            flags:         apple-internal  
            icon:          
            bindings:      .txt, .text, 'TEXT'

真正获得所有捆绑包的唯一方法是在 LaunchService 数据库中查找(我们在上面转储的那个)。如果你只看它是否有 plist 或者是否设置了 bundle 位,你可能会捕获一些甚至许多 bundle,但你不能捕获所有这些。这是 Finder 用来确定的数据库

  • 这个目录是不是一个捆绑包?
  • 这是一个已知的文件扩展名吗?
  • 此文件类型的“打开方式”下应列出哪些应用程序?
  • 我应该使用哪个图标来显示此文件类型?

还有更多的东西。

[编辑:添加了 Leopard 的路径,感谢 Hagelin 的更新]

于 2008-09-23T17:23:54.000 回答
1

<plug>

我的启动工具有一个功能。例如:

% launch -f Guards.oo3 
Guards.oo3: non-application package 
    type: ''    creator: ''
    kind: OmniOutliner 3
    content type ID: com.omnigroup.omnioutliner.oo3-package
    contents: 1 item
    created: 3/6/09 3:36:50 PM
    modified: 3/6/09 4:06:13 PM
    accessed: 4/12/09 1:10:36 PM [only updated by Mac OS X]
    backed up: 12/31/03 6:00:00 PM

% launch -f /Applications/Safari.app
/Applications/Safari.app: scriptable Mac OS X application package 
    type: 'APPL'    creator: 'sfri'
    architecture: PowerPC 7400, Intel 80x86
    bundle ID: com.apple.Safari
    version: 4 Public Beta
    kind: Application
    content type ID: com.apple.application-bundle
    contents: 1 item
    created: 8/21/07 5:11:33 PM
    modified: 2/24/09 7:29:51 PM
    accessed: 4/12/09 1:10:51 PM [only updated by Mac OS X]
    backed up: 12/31/03 6:00:00 PM

您应该能够通过检查输出的第一行是否以“package”结尾来获得所需的内容。

launch也在 Fink 和 MacPorts 中。

</plug>

于 2009-04-12T18:12:26.917 回答
0

应该有一种方法可以从命令行轻松完成,因为作为 AppleScript 用户,我可以使用系统事件来完成。因此,如果一切都失败了,您可以从命令行执行必要的 AppleScript,如下所示:

$ FILE=/Users/myuser/Desktop/foo.rtfd
$ osascript -e "tell application \"System Events\" to get package folder of alias POSIX file \"${FILE}\""

结果是

true
于 2009-04-12T18:07:20.283 回答
-2

一个包应该总是有一个文件`./contents/Info.plist'。您可以在目录中检查它是否存在,如果存在,则它是一个包/捆绑包。

于 2008-09-23T14:03:28.507 回答