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


32

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


Не дурак, хотя я вроде как там ответил. Прости за это.
Даниэль Бек

Ответы:


39

У меня есть более простой способ. Вы будете хотеть Homebrew, если у вас его еще нет:

/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 раз, если бы мог. Отличная информация Работал как шарм для меня в El Capitan.
Райан Уоллс

1
Работаю в Сьерре тоже. Дополнительный совет: UTI являются проблемой, но вы можете использовать "mdls -name 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).

В редакторе списка свойств это выглядит так :

альтернативный текст альтернативный текст

Для этого из командной строки используйте 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 В некотором смысле, да, но этот вопрос конкретно о командной строке. Я подумал, что TextEdit (или редактор списка свойств / Xcode) не подходит; Я только что скопировал эту часть с помощью редактора списков свойств из моего другого ответа в целях иллюстрации. Полезное замечание по идентификатору комплекта.
Даниэль Бек


Если действительно существует альтернативный вход для ИМП, вы согласны с тем, что «команда удаления строки из одного словаря из массива может быть излишне сложным»?
Грэм Перрин

1
@GrahamPerrin Это излишне сложно, потому defaultsчто, кажется, не в состоянии сделать это, и это требует нескольких PlistBuddyзвонков. Но это можно сделать в многократно используемом скрипте оболочки.
Даниэль Бек
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.