问题
The Mac OS X Finder uses the concept of "packages" to make the contents of certain folders opaque to the user. I'm using os.walk()
to enumerate a directory tree and I want to skip enumeration on packages such as application bundles.
The mdls
commandline utility can be used to check whether com.apple.package
is in the kMDItemContentTypeTree
attribute. Is the only/best way to detect whether a folder is a package to drop into os.system
and use mdls
after detecting that the OS is indeed darwin?
As an aside, this solution seems to depend on Spotlight metadata which I understand is populated from the files/directories themselves. This makes me wonder whether there is a method to check whether a directory is a package outside of mdls
. Perhaps I'm missing something.
回答1:
OS X packages (and bundles) are usually defined by their extension. Simply create a directory with an .app
extension to see it be presented as a (broken) application in the Finder.
The official documentation lists the following ways to define bundles:
The Finder considers a directory to be a package if any of the following conditions are true:
- The directory has a known filename extension: .app, .bundle, .framework, .plugin, .kext, and so on.
- The directory has an extension that some other application claims represents a package type; see “Document Packages.”
- The directory has its package bit set.
The preferred way to specify a package is to give the package directory a known filename extension. For the most part, Xcode takes care of this for you by providing templates that apply the correct extension. All you have to do is create an Xcode project of the appropriate type.
The simplest way to detect packages then is to detect those extensions. The quick and dirty way is to simply look for a hard-coded list of extensions, using the above documentation as your guide.
The next step up is to query the OS if a given extension has been registered as a Document Package. See How to check whether directories with a given extension are shown by the Finder as a package?
To detect the package bit on directories, you'll have to use the xattr library to retrieve the u'com.apple.FinderInfo'
key and then use the Finder.h header info to decode the binary data returned; the kHasBundle
flag is 0x2000:
attrs = xattr.getxattr('/path/to/dir', u'com.apple.FinderInfo')
ispackage = bool(ord(attrs[8]) & 0x20) # I *think* this is correct; works for hidden dirs and & 0x40
来源:https://stackoverflow.com/questions/17820117/identify-directories-that-are-packages-in-mac-os-x-with-python