Як змінити програму за замовчуванням для всіх файлів певного типу файлів через термінал в OS X?


32

Як я можу змінити програму за замовчуванням для всіх файлів певного типу файлів через термінал в OS X?


Не дура, хоч я там і відповів. Вибач за це.
Даніель Бек

Для використання енергії мені подобається прийнятий відповідь під останнім запитанням Super User: Чи є більш швидкий спосіб змінити програми за замовчуванням, пов’язані з типами файлів на OS X? . Для простоти мені подобається відповідь Даніеля нижче .
Грем Перрін

Відповіді:


39

У мене є більш простий спосіб. Ви хочете домашню мову, якщо у вас її ще немає:

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

Встановити дуті:

brew install duti

Тепер вам потрібно знайти ідентифікатор додатка, який ви хочете використовувати, і призначити його розширенню, для якого ви хочете використовувати його. У цьому прикладі я вже використовую Дужки для, *.shі я також хочу використовувати його для *.mdфайлів замість xcode.

Отримайте стандартний ідентифікатор програми для .shфайлів:

duti -x sh

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

Останній рядок - ідентифікатор.

Використовуйте цей ідентифікатор програми для всіх .mdфайлів:

duti -s io.brackets.appshell .md all

3
Я б схвалив це 50 разів, якби міг. Чудова інформація. Працював як шарм для мене в Ель-Капітані.
Ryan Walls

1
Працює і в Сьєррі. Додаткова порада: UTI - це біль, але ви можете використовувати "mdls-ім'я kMDItemContentType <file>", щоб знайти UTI для даного файлу (і, отже, розширення).
Адріан

2
Якщо ви ще не пов’язували додаток із чимось таким способом, але знаєте назву свого додатка, ви можете зробити osascript -e 'id of app "$appName"'ідентифікатор будь-якого додатка, встановленого у вашій системі
GrayedFox

1
Тільки для довідки: поєднання підказки від @GrayedFox з duti:duti -s $(osascript -e 'id of app "Visual Studio Code"') .md all
Strajk

18

Редагувати ~/Library/Preferences/com.apple.LaunchServices.plist.

Додайте запис під LSHandlers, що містить UTI (ключ LSHandlerContentType, наприклад public.plain-text) та ідентифікатор пакета програми ( LSHandlerRoleAllнаприклад, com.macromates.textmate).

Це виглядає приблизно так у редакторі списку властивостей :

alt текст alt текст

Для цього з командного рядка використовуйте defaultsабо /usr/libexec/PlistBuddy. Обидва мають широкі набори.

Наприклад, щоб відкрити всі .plistфайли за допомогою Xcode:

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

Звичайно, вам потрібно буде переконатися, що там вже немає іншого запису для UTI com.apple.property-list.

Ось більш повний сценарій, який видалить існуючі записи для UTI та додасть новий. Він може обробляти лише LSHandlerContentTypeта завжди встановлюватиметься LSHandlerRoleAllі має жорстко закодовані ідентифікатори пакету замість параметрів. Крім цього, він повинен працювати досить добре.

#!/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
Найпростіший спосіб - це, мабуть, x=~/Library/Preferences/com.apple.LaunchServices.plist; plutil -convert xml1 $x; open -a TextEdit $xскопіювати та вставити ці записи LSHandlers. Щоб отримати ідентифікатор пакета, ви можете це зробити osascript -e 'bundle identifier of (info for (path to app "TextEdit"))'.
Lri

@Lri Певним чином, так, але це питання стосується саме командного рядка. Я зрозумів, що TextEdit (або редактор списку властивостей / Xcode) не відповідає; Я просто скопіював цю частину з редактором списку властивостей з іншої відповіді для ілюстрації. Корисне зауваження щодо ідентифікатора пакета.
Даніель Бек


Якщо дійсно існує альтернативний вхід для ІМП, ви згодні з тим, що «команда видалення рядка з одного словника з масиву може бути надто складним»?
Грем Перрін

1
@GrahamPerrin Це зайво важко, тому defaultsщо, здається, не здатний це зробити, і для цього потрібно кілька PlistBuddyдзвінків. Але це можливо зробити в сценарії оболонки для багаторазового використання.
Даніель Бек
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.