¿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?


No soy un tonto, a pesar de que respondí allí. Lo siento por eso.
Daniel Beck

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

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

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


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.