Question

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.

Was it helpful?

Solution

Update:

On all systems with Spotlight, using mdls you can detect bundles looking at the kMDItemContentTypeTree property. E.g.:

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

produces the following output for me

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"
)

Whenever you see com.apple.package there, it is supposed to be displayed as a package by Finder. Of course, everything with "bundle" in the name implies that already but not all packages are bundles (bundles are a specific subset of packages that have a well defined directory structure).


Old Answer:

You can get a list of all registered file type extensions, using this command (OS X prior to Leopard):

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

or for Leopard and later:

/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]

OTHER TIPS

This is a bit late, but: it seems you can detect bundles using the mdls command. Specifically, the (multi-line) output of:

mdls -name kMDItemContentTypeTree /Path/To/Directory

Will contain the string

"com.apple.package"

(including the quotation marks, at least as of Lion) somewhere if the directory is a package. If the package is also a bundle, the output will also contain

"com.apple.bundle"

and, last but not least, if it is specifically an application bundle, the output will also contain

"com.apple.application-bundle"

(That's according to some very limited testing, but from what Apple's documentation on Uniform Type Identifiers, and the man page for mdls, this should hold true. And for the items I tested, this was true for non-Apple-provided bundles as well, which is what you would expect given the purpose of UTIs.)

While you can identify some bundles based on the existence 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.

<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>

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

A 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top