我希望能够确定在命令行上从Finder的角度来看,诸如'.app'之类的目录是否被视为包或包。我不认为这对于一个小型的shell程序来说并不困难,但如果我不需要,我宁愿不重新发明轮子。
答案 0 :(得分:6)
这有点晚了,但是:看起来你可以使用mdls命令检测bundle。具体来说,(多行)输出:
mdls -name kMDItemContentTypeTree /Path/To/Directory
将包含字符串
"com.apple.package"
(包括引号,至少是Lion的引号),如果目录是一个包。如果包也是一个包,则输出也将包含
"com.apple.bundle"
,最后但并非最不重要的是,如果它是一个特定的应用程序包,输出也将包含
"com.apple.application-bundle"
(根据一些非常有限的测试,但是根据Apple关于统一类型标识符的文档和mdls的手册页,这应该成立。对于我测试的项目,这对于非Apple提供的情况也是如此捆绑也是如此,这是UTI目的所期望的。)
答案 1 :(得分:4)
虽然您可以根据“./contents/Info.plist”的存在识别一些捆绑包,但并不是所有捆绑包类型都需要它(例如文档和旧版捆绑包)。Finder还将目录标识为基于捆绑包在文件扩展名(.app,.bundle等)上或者如果设置了捆绑位。
要从命令行检查软件包位,请使用:
getFileInfo -aB directory_name
为了抓住所有案件,我会检查:
答案 2 :(得分:3)
在所有使用Spotlight的系统上,使用mdls
可以检测查看kMDItemContentTypeTree属性的包。 E.g:
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”的所有内容都暗示已经但并非所有包都是bundle(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
每个文件扩展名都有标记。如果设置了package标志,那么这是一个包。
E.g。
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 bit,你可能会捕获一些甚至很多bundle,但你无法捕获所有这些。这是Finder用于确定的数据库
还有更多东西。
[编辑:为Leopard增加了路径,感谢Hagelin的更新]
答案 3 :(得分:1)
<plug>
我的launch工具有此功能。例如:
% 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>
答案 4 :(得分: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
答案 5 :(得分:-2)
一个包应该总是有一个文件`./contents/Info.plist'。您可以在目录中检查是否存在,如果是,那么它是一个包/包。