Determinare se una directory è un bundle o pacchetto nel terminale Mac OS X?
Domanda
Vorrei essere in grado di determinare se una directory come '.app' è considerata un pacchetto o un pacchetto dal punto di vista di Finder sulla riga di comando. Non penso che questo sarebbe difficile da fare con un piccolo programma di shell, ma preferirei non reinventare la ruota se non dovessi.
Soluzione
Aggiornamento:
Su tutti i sistemi con Spotlight, utilizzando mdls
è possibile rilevare i bundle guardando la proprietà kMDItemContentTypeTree. Per esempio:.
mdls -name kMDItemContentTypeTree "/Applications/Safari.app"
produce il seguente output per 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"
)
Ogni volta che vedi com.apple.package
lì, dovrebbe essere visualizzato come pacchetto dal Finder. Ovviamente, tutto con & Quot; bundle & Quot; nel nome implica che già ma non tutti i pacchetti sono pacchetti (i pacchetti sono un sottoinsieme specifico di pacchetti che hanno una struttura di directory ben definita).
Vecchia risposta:
Puoi ottenere un elenco di tutte le estensioni di file registrate, usando questo comando (OS X prima di Leopard):
/System/Library/Frameworks/ApplicationServices.framework/Frameworks\
/LaunchServices.framework/Support/lsregister -dump
o per Leopard e successivi:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks\
/LaunchServices.framework/Versions/A/Support/lsregister -dump
Ogni estensione del file contiene flag. Se il flag del pacchetto è impostato, questo è un pacchetto.
per es.
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
Confronta questo con un file che non è un bundle
claim id: 2484731904
name: TEXT
role: viewer
flags: apple-internal
icon:
bindings: .txt, .text, 'TEXT'
L'unico modo per ottenere davvero tutti i bundle è cercare nel database LaunchService (quello che abbiamo scaricato sopra). Se passi semplicemente se ha un plist o meno o se il bit del bundle è impostato o meno, potresti catturare alcuni o anche molti bundle, ma non puoi catturarli tutti. Questo è il database che Finder utilizza per determinare
- Questa directory è un bundle o no?
- È un'estensione di file conosciuta o no?
- Quali applicazioni devono essere elencate in " Apri con " per questo tipo di file?
- Quale icona devo usare per visualizzare questo tipo di file?
e alcune altre cose.
[EDIT: percorso aggiunto per Leopard, grazie a Hagelin per l'aggiornamento]
Altri suggerimenti
Questo è un po 'tardi, ma: sembra che tu possa rilevare i bundle usando il comando mdls. In particolare, l'output (multilinea) di:
mdls -name kMDItemContentTypeTree /Path/To/Directory
Conterrà la stringa
"com.apple.package"
(comprese le virgolette, almeno a partire da Lion) da qualche parte se la directory è un pacchetto. Se il pacchetto è anche un pacchetto, anche l'output conterrà
"com.apple.bundle"
e, ultimo ma non meno importante, se si tratta specificamente di un pacchetto di applicazioni, anche l'output conterrà
"com.apple.application-bundle"
(Questo è secondo alcuni test molto limitati, ma dalla documentazione di Apple sugli Uniform Type Identificers e dalla pagina man di mdls, questo dovrebbe essere vero. E per gli articoli che ho testato, questo era vero per i non forniti da Apple anche bundle, che è quello che ti aspetteresti dato lo scopo delle UTI.)
Sebbene sia possibile identificare alcuni bundle in base all'esistenza di './contents/Info.plist" ;, non è necessario per tutti i tipi di bundle (ad esempio documenti e bundle legacy). Finder identifica anche una directory come bundle in base all'estensione del file (.app, .bundle, ecc.) O se il bit del bundle è impostato.
Per controllare il bit del bundle dalla riga di comando utilizzare:
getFileInfo -aB directory_name
Per catturare tutti i casi vorrei controllare:
- Il bit del bundle è impostato?
- In caso contrario, ha un'estensione di file che lo identifica come un bundle? (vedi La risposta di Mecki )
- In caso contrario, probabilmente non è un pacchetto.
<plug>
Il mio strumento launch ha una funzione per questo. Ad esempio:
% 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
Dovresti essere in grado di ottenere ciò che desideri controllando per vedere se la prima riga dell'output termina in 'pacchetto'.
launch
è anche in Fink e MacPorts.
</plug>
Dovrebbe esserci un modo per farlo facilmente dalla riga di comando, perché come utente AppleScript, posso farlo usando System Events. Quindi, se tutto il resto fallisce, puoi eseguire il necessario AppleScript dalla riga di comando come segue:
$ FILE=/Users/myuser/Desktop/foo.rtfd
$ osascript -e "tell application \"System Events\" to get package folder of alias POSIX file \"${FILE}\""
il risultato è
true
Un bundle dovrebbe sempre avere un file `./contents/Info.plist '. Puoi verificarne l'esistenza in una directory, in tal caso si tratta di un pacchetto / bundle.