Questão Como alterar o aplicativo padrão para todos os arquivos de tipo de arquivo específico por meio do terminal no OS X?


Como posso alterar o aplicativo padrão para todos os arquivos de um determinado tipo de arquivo através do Terminal no OS X?


25


origem


Não um dupe, mesmo que eu tenha respondido lá. Me desculpe por isso. - Daniel Beck♦
Para uso de energia, eu gosto do resposta aceita sob uma pergunta de superusuário mais recente, Existe uma maneira mais rápida de alterar aplicativos padrão associados a tipos de arquivo no OS X?. Para simplificar, gosto A resposta de Daniel abaixo. - Graham Perrin


Respostas:


Eu tenho um jeito mais simples. Você vai querer Homebrew se você ainda não tem:

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

Instale o duti:

brew install duti

Agora você precisa encontrar o ID do aplicativo que deseja usar e atribuí-lo à extensão para a qual deseja usá-lo. Neste exemplo, eu já uso Brackets para *.sh e eu também quero usá-lo para *.md arquivos em vez de xcode.

Obter o ID do aplicativo padrão para .sh arquivos:

duti -x sh

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

A última linha é o id.

Use este id de aplicativo para todos .md arquivos:

duti -s io.brackets.appshell .md all

27



Poderia upvote isso 50 vezes se eu pudesse. Ótima informação. Trabalhou como um encanto para mim em El Capitan. - Ryan Walls
Trabalhando na Sierra também. Dica extra: UTIs são um problema, mas você pode usar "mdls -name kMDItemContentType <file>" para encontrar o UTI para um determinado arquivo (e, portanto, extensão). - Adrian
Isso é incrível. obrigado. - Astrid
Se você ainda não associou um aplicativo a algo desse jeito, mas sabe o nome dele, pode fazer osascript -e 'id of app "$appName"' para obter o ID de qualquer aplicativo instalado no seu sistema - GrayedFox


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

Adicione uma entrada em LSHandlers, contendo a UTI (chave LSHandlerContentType, por exemplo. public.plain-text) e identificador do pacote de aplicativos (LSHandlerRoleAll, por exemplo. com.macromates.textmate).

Parece assim em Editor de lista de propriedades:

alt text alt text

Para fazer isso a partir da linha de comando, use defaults ou /usr/libexec/PlistBuddy. Ambos possuem extensas manpages.

Por exemplo, para abrir todos .plist arquivos usando Xcode:

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

Claro, você precisa ter certeza de que não há mais uma entrada para a UTI com.apple.property-list já está lá.

Aqui está um script mais completo que remove as entradas existentes para uma UTI e adiciona uma nova. Só pode lidar com LSHandlerContentTypee sempre definirá LSHandlerRoleAlle tem IDs de pacotes incorporados em vez de parâmetros. Fora isso, deve funcionar muito bem.

#!/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

16



A maneira mais fácil é provavelmente x=~/Library/Preferences/com.apple.LaunchServices.plist; plutil -convert xml1 $x; open -a TextEdit $x e copie e cole essas entradas do LSHandlers. Para obter o identificador do pacote, você pode fazer osascript -e 'bundle identifier of (info for (path to app "TextEdit"))'. - user495470
@Lri De certa forma, sim, mas esta questão é especificamente sobre a linha de comando. Eu percebi que TextEdit (ou Property List Editor / Xcode) não se qualifica; Eu copiei essa parte com o Property List Editor da minha outra resposta para fins de ilustração. Observação útil no identificador do pacote. - Daniel Beck♦
Crédito para Daniel, eu pedi emprestado para isso uma resposta para uma pergunta no Ask Different, O Finder e o comando “open” podem tratar arquivos com .sh ou outras extensões típicas, como arquivos de comando?. - Graham Perrin
Se lá faz existe uma entrada alternativa para o UTI, você concorda que "a remoção de linha de comando de um único dicionário de um array pode ser desnecessariamente difícil"? - Graham Perrin
@GrahamPerrin É desnecessariamente difícil porque defaults não parece ser capaz de fazer isso, e isso requer alguns PlistBuddy chamadas. Mas é possível fazer isso em um script de shell reutilizável. - Daniel Beck♦