Удобный способ изменить настройки приложения (он же настройки) в macOS – использовать меню пользовательского интерфейса как Application Name > Preferences… или нажав горячие клавиши ⌘+, из данного приложения.
Однако этот метод, основанный на пользовательском интерфейсе, не позволяет вам управлять версиями ваших настроек с помощью git или программно устанавливать настройки ваших приложений из сценария оболочки. Здесь пригодится инструмент командной строки defaults в macOS. defaults позволяет читать, записывать и удалять пользовательские настройки из командной строки.
defaults получите доступ к системе пользовательских настроек Mac OS X, то есть к настройкам. Все приложения Mac OS X используют defaults систему для записи пользовательских настроек и другой информации, которая должна поддерживаться, когда приложения не запущены.
Стоит отметить, что вы часто можете получить доступ к большему количеству опций через командную строку defaults, чем при использовании пользовательского интерфейса. Также имейте в виду, что если вы измените настройки запущенного приложения, приложение может не увидеть изменения до тех пор, пока оно не будет перезапущено и/или может перезаписать изменение.
Пользовательские настройки по умолчанию относятся к доменам, которые обычно представляют собой уникальный домен для каждого приложения. Каждый домен будет представлен словарем ключа/значения; например, “Default Font” = “Arial”. Ключи всегда являются строками, но значениями могут быть сложные структуры данных, включающие массивы, словари, строки и двоичные данные. Эти структуры данных хранятся в виде списков свойств XML и известны как plist.
defaults поставляется с несколькими доступными командами для чтения, записи и удаления настроек пользовательских приложений из командной строки.
read | выводит настройки пользователя на стандартный вывод |
read-type | выводит тип plist для заданного ключа |
write | введите значение для данного ключа |
rename | переименовать ключ |
import | импортируйте plist в заданный домен |
export | экспортируйте домен и все ключи в виде списка |
delete | удалить данный ключ или домен / все ключи для данного домена |
domains | печатает названия всех доменов |
find | выполните поиск по всем доменам, ключам и значениям для данного слова |
Обязательно ознакомьтесь с man defaults для получения полной информации или просто запустите командную строку без каких-либо аргументов, чтобы defaults получить базовое справочное сообщение.
Если вы просто используете defaults domains, в итоге может получиться длинный список доменов, разделенных запятыми, который не обязательно легко читать.
[…] com.apple.Spotlight, com.apple.SystemProfiler, com.apple.TelephonyUtilities, com.apple.Terminal, com.apple.TextEdit, com.apple.UIKit, com.apple.UserAccountUpdater, com.apple.WebKit.WebContent, com.apple.accounts […]
Вы можете легко улучшить вывод списка, используя tr что-то вроде defaults domains | tr ‘,’ ‘\n’.
[…] com.apple.Terminal
com.apple.TextEdit
[…]
В итоге вы все равно получите сотни строк, и вам, возможно, придется использовать grep, если вы не уверены, какие домены вы ищете.
Допустим, вы хотите программно включить проверку грамматики с помощью орфографии в TextEdit. Чтобы найти домен, мы сначала воспользуемся приведенной выше командой defaults domains и grep для имени приложения.
[me@andreyex: ~]$ defaults domains | tr ',' '\n' | grep -i textedit com.apple.TextEdit
Тогда мы можем просто прочитать существующие значения по умолчанию для TextEdit с помощью defaults read <domain>. Вы не увидите там ничего необычного, поскольку интересующий нас параметр еще не будет представлен.
[me@andreyex: ~]$ defaults read com.apple.TextEdit { NSNavPanelExpandedSizeForOpenMode = "{799, 448}"; "NSWindow Frame NSNavPanelAutosaveName" = "320 334 799 390 0 0 1440 877 "; }
Чтобы узнать название опции, нам нужно зайти в пользовательский интерфейс TextEdit и отредактировать настройки вручную. Используйте ⌘+, затем в New Document установите флажок с именем Check grammar with spelling. Закройте панель настроек.
Теперь, если вы снова запустите команду defaults, ваш новый вывод должен выглядеть так, как показано ниже, и включать CheckGrammarWithSpelling ключ.
[me@andreyex: ~]$ defaults read com.apple.TextEdit { CheckGrammarWithSpelling = 1; NSNavLastRootDirectory = "~/Library/Mobile Documents/com~apple~TextEdit/Documents"; NSNavPanelExpandedSizeForOpenMode = "{799, 448}"; "NSWindow Frame NSNavPanelAutosaveName" = "320 334 799 390 0 0 1440 877 "; }
Итак, теперь мы знаем, что ключом, который мы хотим использовать в нашем скрипте, является CheckGrammarWithSpelling, а домен – com.apple.TextEdit.
Этот метод отлично работает для простых параметров, но в некоторых случаях вам, возможно, придется прибегнуть к использованию diff при полном экспорте defaults read, чтобы легко найти затронутый домен и ключи.
Чтобы записать новое значение в ключ, вам нужно сначала узнать, каков тип значения. Именно здесь defaults read-type становится необходимой команда. Ключ должен присутствовать в настройках по умолчанию, чтобы успешно вернуться. Из нашего предыдущего примера TextEdit CheckGrammarWithSpelling ключ ожидает логическое значение.
[me@andreyex: ~]$ defaults read-type com.apple.TextEdit CheckGrammarWithSpelling Type is boolean
Как только вы это узнаете, вы сможете легко ввести свои новые настройки с помощью команды defaults write.
[me@andreyex: ~]$ defaults write com.apple.TextEdit CheckGrammarWithSpelling -bool true [me@andreyex: ~]$ defaults read com.apple.TextEdit { CheckGrammarWithSpelling = 1; NSNavLastRootDirectory = "~/Library/Mobile Documents/com~apple~TextEdit/Documents"; NSNavPanelExpandedSizeForOpenMode = "{799, 448}"; "NSWindow Frame NSNavPanelAutosaveName" = "320 334 799 390 0 0 1440 877 "; }
Обратите внимание, что в этом случае из-за логического значения также будет работать использование целого числа; например: defaults write com.apple.TextEdit CheckGrammarWithSpelling 1.
В случае, если вы хотите полностью сбросить конфигурацию defaults приложения или удалить внесенные изменения, вы можете захотеть удалить ключ или домен. Тем не менее, мы бы рекомендовали вместо этого перезаписать ключ предпочтений новым значением, поскольку это менее разрушительно.
В нашем предыдущем примере, если мы хотим восстановить наши настройки TextEdit по умолчанию, мы можем просто выполнить defaults delete по данному ключу.
[me@andreyex: ~]$ defaults delete com.apple.TextEdit CheckGrammarWithSpelling [me@andreyex: ~]$ defaults read com.apple.TextEdit { NSNavLastRootDirectory = "~/Library/Mobile Documents/com~apple~TextEdit/Documents"; NSNavPanelExpandedSizeForOpenMode = "{799, 448}"; "NSWindow Frame NSNavPanelAutosaveName" = "320 334 799 390 0 0 1440 877 "; }
Если вы полностью удалите домен, то при следующем чтении этого домена произойдет сбой.
[me@andreyex: ~]$ defaults delete com.apple.TextEdit [me@andreyex: ~]$ defaults read com.apple.TextEdit 2020-05-03 21:38:44.129 defaults[28419:688204] Domain /Users/me/Library/Containers/com.apple.TextEdit/Data/Library/Preferences/com.apple.TextEdit does not exist
Настройки будут отображаться снова при следующем запуске приложения, поскольку оно запишет новый набор значений в defaults.
Некоторые люди зашли довольно далеко в том, как настроить свою рабочую среду macOS с помощью полностью написанной по сценарию настройки своих различных приложений, включая само приложение Finder. Хорошим примером для проверки является конфигурация от Матиаса Байненса, а также большой список dotFiles различных пользователей, куратором которых является Уилсон Мар.