Определите, является ли каталог пакетом или пакетом в терминале Mac OS X?
Вопрос
Я хотел бы иметь возможность определить, считается ли каталог, такой как «.app», пакетом или пакетом с точки зрения Finder в командной строке.Я не думаю, что это будет сложно сделать с помощью небольшой программы-оболочки, но я бы предпочел не изобретать велосипед, если в этом нет необходимости.
Решение
Обновлять:
Во всех системах с 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 как пакет.Конечно, все, что содержит слово «bundle» в названии, подразумевает, что уже, но не все пакеты являются пакетами (пакеты — это определенное подмножество пакетов, которые имеют четко определенную структуру каталогов).
Старый ответ:
Вы можете получить список всех зарегистрированных расширений типов файлов, используя эту команду (OS X до Leopard):
/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 использует для определения
- Является ли этот каталог пакетом или нет?
- Это известное расширение файла или нет?
- Какие приложения должны быть указаны в разделе «Открыть с помощью» для этого типа файлов?
- Какой значок следует использовать для отображения этого типа файла?
и еще кое-что.
[РЕДАКТИРОВАТЬ:Добавлен путь для Леопарда, спасибо Хагелину за обновление]
Другие советы
Это немного поздно, но:кажется, вы можете обнаружить пакеты с помощью команды mdls.В частности, (многострочный) вывод:
mdls -name kMDItemContentTypeTree /Path/To/Directory
Будет содержать строку
"com.apple.package"
(включая кавычки, по крайней мере, в Lion) где-нибудь, если каталог является пакетом.Если пакет также является пакетом, выходные данные также будут содержать
"com.apple.bundle"
и, наконец, если это конкретно пакет приложения, выходные данные также будут содержать
"com.apple.application-bundle"
(Это согласно некоторым очень ограниченным тестам, но судя по документации Apple по унифицированным идентификаторам типов и странице руководства по mdls, это должно быть правдой.И для продуктов, которые я тестировал, это справедливо и для пакетов, не предоставленных 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
Вы сможете получить то, что хотите, проверив, заканчивается ли первая строка вывода на «пакет».
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'.Вы можете проверить его наличие в каталоге, если да, то это пакет/пакет.