¿Cómo cambiar la aplicación predeterminada para todos los archivos de un tipo de archivo particular a través del terminal en OS X?

32

¿Cómo puedo cambiar la aplicación predeterminada para todos los archivos de un tipo de archivo en particular a través de la Terminal en OS X?

yashodhan
fuente
No soy un tonto, a pesar de que respondí allí. Lo siento por eso.
Daniel Beck
Para el uso de energía, me gusta la respuesta aceptada en una pregunta más reciente de Superusuario, ¿hay una forma más rápida de cambiar las aplicaciones predeterminadas asociadas con los tipos de archivos en OS X? . Por simplicidad, me gusta la respuesta de Daniel a continuación .
Graham Perrin

Respuestas:

39

Tengo una manera más simple. Querrás Homebrew si aún no lo tienes:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Instalar duti:

brew install duti

Ahora necesita encontrar la identificación de la aplicación que desea usar y asignarla a la extensión para la que desea usarla. En este ejemplo, ya uso Brackets para *.shy también quiero usarlo para *.mdarchivos en lugar de xcode.

Obtenga la identificación de la aplicación predeterminada para los .sharchivos:

duti -x sh

output:
  Brackets.app
  /opt/homebrew-cask/Caskroom/brackets/1.6/Brackets.app
  io.brackets.appshell

La última línea es la identificación.

Use esta identificación de la aplicación para todos los .mdarchivos:

duti -s io.brackets.appshell .md all
quemaduras mate
fuente
3
Votaría esto 50 veces si pudiera. Gran información Funcionó como un encanto para mí en El Capitán.
Ryan Walls
1
Trabajando en Sierra también. Consejo adicional: las infecciones urinarias son un problema, pero puede usar "mdls -name kMDItemContentType <file>" para encontrar la infección urinaria para un archivo determinado (y, por lo tanto, la extensión).
Adrian
2
Si aún no ha asociado una aplicación con algo de esta manera, pero conoce el nombre de su aplicación, puede hacer osascript -e 'id of app "$appName"'para obtener la identificación de cualquier aplicación instalada en su sistema
GrayedFox
1
Solo como referencia: combinando un consejo de @GrayedFox con duti:duti -s $(osascript -e 'id of app "Visual Studio Code"') .md all
Strajk
18

Editar ~/Library/Preferences/com.apple.LaunchServices.plist.

Agregue una entrada debajo LSHandlers, que contenga la UTI (clave LSHandlerContentType, por ejemplo public.plain-text) y el identificador del paquete de la aplicación ( LSHandlerRoleAll, por ejemplo com.macromates.textmate).

Se ve así en el Editor de la lista de propiedades :

texto alternativo texto alternativo

Para hacer esto desde la línea de comandos, use defaultso /usr/libexec/PlistBuddy. Ambos tienen páginas de manual extensas.

Por ejemplo, para abrir todos los .plistarchivos usando Xcode:

defaults write com.apple.LaunchServices LSHandlers -array-add '{ LSHandlerContentType = "com.apple.property-list"; LSHandlerRoleAll = "com.apple.dt.xcode"; }'

Por supuesto, deberá asegurarse de que ya no haya otra entrada para la infección urinaria com.apple.property-listallí.

Aquí hay un script más completo que eliminará las entradas existentes para una UTI y agregará una nueva. Solo puede manejar LSHandlerContentType, y siempre se configurará LSHandlerRoleAll, y tiene ID de paquete codificados en lugar de parámetros. Aparte de eso, debería funcionar bastante bien.

#!/usr/bin/env bash

PLIST="$HOME/Library/Preferences/com.apple.LaunchServices.plist"
BUDDY=/usr/libexec/PlistBuddy

# the key to match with the desired value
KEY=LSHandlerContentType

# the value for which we'll replace the handler
VALUE=public.plain-text

# the new handler for all roles
HANDLER=com.macromates.TextMate

$BUDDY -c 'Print "LSHandlers"' $PLIST >/dev/null 2>&1
ret=$?
if [[ $ret -ne 0 ]] ; then
        echo "There is no LSHandlers entry in $PLIST" >&2
        exit 1
fi

function create_entry {
        $BUDDY -c "Add LSHandlers:$I dict" $PLIST
        $BUDDY -c "Add LSHandlers:$I:$KEY string $VALUE" $PLIST
        $BUDDY -c "Add LSHandlers:$I:LSHandlerRoleAll string $HANDLER" $PLIST
}

declare -i I=0
while [ true ] ; do
        $BUDDY -c "Print LSHandlers:$I" $PLIST >/dev/null 2>&1
        [[ $? -eq 0 ]] || { echo "Finished, no $VALUE found, setting it to $HANDLER" ; create_entry ; exit ; }

        OUT="$( $BUDDY -c "Print 'LSHandlers:$I:$KEY'" $PLIST 2>/dev/null )"
        if [[ $? -ne 0 ]] ; then 
                I=$I+1
                continue
        fi

        CONTENT=$( echo "$OUT" )
        if [[ $CONTENT = $VALUE ]] ; then
                echo "Replacing $CONTENT handler with $HANDLER"
                $BUDDY -c "Delete 'LSHandlers:$I'" $PLIST
                create_entry
                exit
        else
                I=$I+1 
        fi
done
Daniel Beck
fuente
3
La forma más fácil es probablemente x=~/Library/Preferences/com.apple.LaunchServices.plist; plutil -convert xml1 $x; open -a TextEdit $xcopiar y pegar esas entradas de LSHandlers. Para obtener el identificador de paquete que puede hacer osascript -e 'bundle identifier of (info for (path to app "TextEdit"))'.
Lri
@Lri En cierto modo, sí, pero esta pregunta es específicamente sobre la línea de comando. Me imaginé que TextEdit (o Editor de lista de propiedades / Xcode) no califica; Acabo de copiar esa parte con el Editor de lista de propiedades de mi otra respuesta con fines ilustrativos. Comentario útil sobre el identificador de paquete.
Daniel Beck
Gracias a Daniel, tomé prestado esto para responder a una pregunta en Preguntar diferente, ¿Puede Finder y el comando "abrir" tratar los archivos con .sh u otras extensiones típicas como los archivos .command? .
Graham Perrin
Si hay qué existe una entrada alternativa para la infección del tracto urinario, estaría de acuerdo en que "la eliminación de líneas de comandos de un único diccionario de una matriz puede ser innecesariamente difícil"?
Graham Perrin
1
@GrahamPerrin Es innecesariamente difícil porque defaultsno parece ser capaz de hacerlo y requiere algunas PlistBuddyllamadas. Pero es posible hacerlo en un script de shell reutilizable.
Daniel Beck