确定目录是Mac OS X终端中的捆绑包还是软件包?
从命令行的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>