I'd like to be able to determine if a directory such as a '.app' is considered to be a package or bundle from Finder's point of view on the command line. I don't think this would be difficult to do with a small shell program, but I'd rather not re-invent the wheel if I don't have to.
views:
1388answers:
5A bundle should always have a file `./contents/Info.plist'. You can check for the existance of this in a directory, if so then it's a package/bundle.
While you can identify some bundles based on the existens of './contents/Info.plist", it isn't required for all bundle types (e.g. documents and legacy bundles). Finder also identifies a directory as a bundle based on file extension (.app, .bundle, etc) or if the bundle bit is set.
To check the bundle bit from the command line use:
getFileInfo -aB directory_name
In order to catch all cases I would check:
- Is the bundle bit set?
- If not, does it have a file extension that identifies it as a bundle? (see Mecki's answer)
- If not, it probably isn't a bundle.
You can get a list of all registered file type extensions, using this command:
/System/Library/Frameworks/ApplicationServices.framework/Frameworks\
/LaunchServices.framework/Support/lsregister -dump
or for Leopard
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks\
/LaunchServices.framework/Versions/A/Support/lsregister -dump"
Every file extension there has flags. If the package flag is set, this is a 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
Compare this to a file that is no bundle
claim id: 2484731904
name: TEXT
role: viewer
flags: apple-internal
icon:
bindings: .txt, .text, 'TEXT'
The only way to really get all bundles is by looking up in the LaunchService database (the one we dumped above). If you just go by whether it has a plist or not or whether the bundle bit is set or not, you might catch some or even many bundles, but you can't catch all of them. This is the database Finder uses to determine
- Is this directory a bundle or not?
- Is this a known file extension or not?
- Which applications should be listed under "Open With" for this file type?
- Which icon should I use for displaying this file type?
and some more stuff.
[EDIT: Added path for Leopard, thanks to Hagelin for the update]
There ought to be a way to do it easily from the command line, because as an AppleScript user, I can do it using System Events. So if all else fails, you can execute the necessary AppleScript from the command line as follows:
$ FILE=/Users/myuser/Desktop/foo.rtfd
$ osascript -e "tell application \"System Events\" to get package folder of alias POSIX file \"${FILE}\""
result is
true
<plug>
My launch tool has a feature for this. For example:
% 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
You should be able to get what you want by checking to see if the first line of output ends in 'package'.
launch
is in Fink and MacPorts too.
</plug>