Mac OS X ターミナルでディレクトリがバンドルであるかパッケージであるかを判断しますか?
質問
コマンドライン上の Finder の観点から、「.app」などのディレクトリがパッケージとみなされているのかバンドルとみなされているのかを判断できるようにしたいと考えています。小さなシェル プログラムでこれを行うのは難しくないと思いますが、必要がなければ車輪の再発明はしたくないと思います。
解決
アップデート:
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 でパッケージとして表示されることになっています。もちろん、名前に「バンドル」が含まれているものはすべて、すべてではありませんが、すでにパッケージがバンドルであることを意味します (バンドルは、明確に定義されたディレクトリ構造を持つパッケージの特定のサブセットです)。
古い答え:
次のコマンドを使用して、登録されているすべてのファイル タイプ拡張子のリストを取得できます (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 のパスを追加しました]
他のヒント
少し遅れましたが、次のとおりです。mdlsコマンドを使用するとバンドルを検出できるようです。具体的には、次の (複数行) 出力:
mdls -name kMDItemContentTypeTree /Path/To/Directory
文字列が含まれます
"com.apple.package"
(少なくとも Lion では引用符を含む) ディレクトリがパッケージの場合はどこかにあります。パッケージがバンドルでもある場合、出力には次の内容も含まれます。
"com.apple.bundle"
最後になりましたが、特にアプリケーション バンドルの場合、出力には次の内容も含まれます。
"com.apple.application-bundle"
(これはいくつかの非常に限定されたテストによるものですが、Uniform Type Identifiers に関する Apple のドキュメントと mdls の man ページからすると、これは真実であるはずです。そして、私がテストした項目では、これは Apple 以外が提供するバンドルにも当てはまり、UTI の目的を考えると、これは予想されることです。)
一部のバンドルは「./contents/Info.plist」の存在に基づいて識別できますが、すべてのバンドル タイプ (例:ドキュメントとレガシーバンドル)。また、Finder は、ファイル拡張子 (.app、.bundle など) またはバンドル ビットが設定されているかどうかに基づいて、ディレクトリをバンドルとして識別します。
コマンドラインからバンドルビットを確認するには、以下を使用します。
getFileInfo -aB directory_name
すべてのケースをキャッチするために、次のことを確認します。
- バンドルビットは設定されていますか?
- そうでない場合、バンドルであることを示すファイル拡張子はありますか?(見る メッキーさんの答えは)
- そうでない場合は、おそらくバンドルではありません。
<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」で終わるかどうかを確認することで、必要なものを取得できるはずです。
launch
Fink と MacPorts にもあります。
</plug>
AppleScript ユーザーとしては、システム イベントを使用して実行できるため、コマンド ラインから簡単に実行する方法があるはずです。したがって、他のすべてが失敗した場合は、次のようにコマンドラインから必要な AppleScript を実行できます。
$ FILE=/Users/myuser/Desktop/foo.rtfd
$ osascript -e "tell application \"System Events\" to get package folder of alias POSIX file \"${FILE}\""
結果は
true
バンドルには常にファイル `./contents/Info.plist' が必要です。これがディレクトリ内に存在するかどうかを確認できます。存在する場合、それはパッケージ/バンドルです。