确定目录是Mac OS X终端中的捆绑包还是软件包?

时间:2020-03-06 14:36:01  来源:igfitidea点击:

从命令行的Finder角度来看,我想能够确定某个目录(例如" .app")是否被视为软件包或者捆绑软件。我认为使用小型Shell程序很难做到这一点,但是我宁愿不要重新发明轮子。

解决方案

捆绑软件应始终包含文件" ./contents/Info.plist"。我们可以检查目录中是否存在此文件,如果是,则为打包文件/捆绑包。

虽然我们可以根据'./contents/Info.plist'的存在来识别某些包,但并非所有包类型(例如文档和旧版包)都需要它。 (.app,.bundle等),或者是否设置了bundle位。

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

getFileInfo -aB directory_name

为了捕获所有情况,我将检查:

  • 捆绑包设置了吗?
  • 如果不是,它是否具有将其标识为捆绑软件的文件扩展名? (请参阅Mecki的答案)
  • 如果没有,它可能不是捆绑包。

更新:

在所有带有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或者是否设置了捆绑软件位进行检查,我们可能会捕获一些甚至许多捆绑软件,但无法捕获所有捆绑软件。这是Finder用来确定的数据库

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

还有更多的东西。

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

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

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

结果是

true

<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"结尾,我们应该能够获得所需的内容。

"启动"也在Fink和MacPorts中。

</ plug>