Jak zmienić domyślną aplikację dla wszystkich plików określonego typu przez terminal w OS X?

32

Jak mogę zmienić domyślną aplikację dla wszystkich plików określonego typu poprzez Terminal w OS X?

yashodhan
źródło
To nie dupek, chociaż w pewnym sensie tam odpowiedziałem. Przepraszam za to.
Daniel Beck

Odpowiedzi:

39

Mam prostszy sposób. Będziesz chciał Homebrew, jeśli jeszcze go nie masz:

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

Zainstaluj duti:

brew install duti

Teraz musisz znaleźć identyfikator aplikacji, której chcesz użyć, i przypisać ją do rozszerzenia, którego chcesz używać. W tym przykładzie używam już nawiasów *.shi chcę go również używać do *.mdplików zamiast xcode.

Uzyskaj domyślny identyfikator aplikacji dla .shplików:

duti -x sh

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

Ostatnia linia to identyfikator.

Użyj tego identyfikatora aplikacji dla wszystkich .mdplików:

duti -s io.brackets.appshell .md all
matowe oparzenia
źródło
3
Głosowałbym za tym 50 razy, gdybym mógł. Świetna informacja. Dla mnie działał jak urok w El Capitan.
Ryan Walls
1
Pracuję także w Sierra. Dodatkowa wskazówka: UTI są uciążliwe, ale możesz użyć „mdls -name kMDItemContentType <plik>”, aby znaleźć UTI dla danego pliku (i dlatego rozszerzenia).
Adrian
2
Jeśli nie powiązałeś jeszcze aplikacji z czymś w ten sposób, ale znasz nazwę swojej aplikacji, możesz zrobić, osascript -e 'id of app "$appName"'aby uzyskać identyfikator dowolnej aplikacji zainstalowanej w systemie
GrayedFox
1
Tylko dla odniesienia: połączenie końcówki @GrayedFox z duti:duti -s $(osascript -e 'id of app "Visual Studio Code"') .md all
Strajk
18

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

Dodaj pozycję pod LSHandlerszawierającą identyfikator UTI (klucz LSHandlerContentType, np. public.plain-text) I identyfikator pakietu aplikacji ( LSHandlerRoleAllnp com.macromates.textmate.).

Wygląda to tak w Edytorze list właściwości :

alternatywny tekst alternatywny tekst

Aby to zrobić z wiersza poleceń, użyj defaultslub /usr/libexec/PlistBuddy. Oba mają obszerne strony.

Na przykład, aby otworzyć wszystkie .plistpliki za pomocą Xcode:

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

Oczywiście, musisz upewnić się, że nie ma już innego wpisu dla UTI com.apple.property-listjuż tam.

Oto bardziej kompletny skrypt, który usunie istniejące wpisy dla UTI i doda nowy. Może obsłużyć LSHandlerContentTypei zawsze będzie ustawiony LSHandlerRoleAll, i ma zakodowane identyfikatory pakietów zamiast parametrów. Poza tym powinien działać całkiem dobrze.

#!/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
źródło
3
Najłatwiejszym sposobem jest prawdopodobnie x=~/Library/Preferences/com.apple.LaunchServices.plist; plutil -convert xml1 $x; open -a TextEdit $xskopiowanie i wklejenie tych wpisów LSHandler. Aby uzyskać identyfikator pakietu, możesz to zrobić osascript -e 'bundle identifier of (info for (path to app "TextEdit"))'.
Lri
@Lri W pewnym sensie tak, ale to pytanie dotyczy konkretnie wiersza poleceń. Doszedłem do wniosku, że TextEdit (lub edytor listy właściwości / Xcode) się nie kwalifikuje; Właśnie skopiowałem tę część za pomocą edytora listy właściwości z mojej innej odpowiedzi w celach ilustracyjnych. Przydatna uwaga na temat identyfikatora pakietu.
Daniel Beck
Jeśli tam nie istnieje alternatywny wpis dla UTI Zgodzisz się, że „wiersz polecenia usunięcie jednego słownika z tablicy może być niepotrzebnie trudne”?
Graham Perrin
1
@GrahamPerrin Jest to niepotrzebnie trudne, ponieważ defaultswydaje się, że nie jest w stanie tego zrobić i wymaga kilku PlistBuddypołączeń. Ale można to zrobić w skrypcie powłoki wielokrotnego użytku.
Daniel Beck