AppleScript — встроенный в Mac OS X язык сценариев. С момента появления в 1990 году в операционных системах System, AppleScript превратился в мощный инструмент, позволяющий управлять операционной системой, приложениями и объектами системы. AppleScript имеет, как говорят, «юзер-френли» синтаксис. Поэтому любой мало-мальски разбирающийся в английском языке пользователь (умеющий читать и создавать алгоритмы), может с лёгкостью понять и освоить этот скриптовый язык. Сам процесс «программирования» на AppleScript больше похож на монолог с ситемой на английском, чем на программирование. Тем не менее, AppleScript относят к объекто-ориентированным языкам, и с помощью AppleScript Studio входящего в пакет для разработчиков Xcode, на нём можно создавать даже целые программы. Для нас же AppleScript интересен в первую очередь как средство эффективной автоматизации различных рутинных и повторяющихся действий, и при этом не обременяет изучением сложных языков программирования. Конечно, bash (shell) скрипты являются более гибким средством, но когда речь заходит о GUI (графическом пользовательском интерфейсе), то bash нам ни как не друг, в отличии от AppleScript, который позволяет создавать сценарии способные взаимодействовать с системой и пользователем через графический интерфейс. К тому же в AppleScript можно легко внедрять элементы «консоли», то есть выполнять «терминальные» команды внутри AppleScript. Но об этом чуть позже.
Весь процесс создания рабочего скрипта происходит или в Xcode, или в приложении Редактор AppleScript. Последний находится в папке Программы > Утилиты, с ним мы и будем работать. В AppleScript для меня самое интересное и ценное то, что рабочий скрипт можно сохранить в виде программы, а затем поделиться ею с другими «маководами» и использовать её на других компьютерах Mac. Ну что ж, запустим Редактор AppleScript и посмотрим на его рабочее пространство:Сам Редактор AppleScript выглядит довольно просто и лаконично: ничего лишнего. Из распоряжения имеются такие кнопки:
- Запись – позволяет записывать происходящее в системе. Если вы обладаете абсолютно нулевыми навыками в скриптовом программировании, нажмите эту кнопку, создайте на Рабочем столе (к примеру) папку. Затем остановите запись. В окне редактора появится код ваших действий. Если теперь этот код сохранить как программу и запустить, то выполниться точно такое же действие. Это очень удобно использовать для самообучения, особенно когда не ясно как реализовать ту или иную функцию.
- Остановить – кнопка для остановки записи сценария.
- Запустить – выполняет запуск скрипта
- Компилировать – выполняет проверку кода и при ошибке сообщает об этом. К тому же её нажатие как бы «включает» подсветку синтаксиса, что весьма удобно и наглядно разделяет код. В общем-то эту кнопку можно обозвать кнопкой Отладка.
Как я уже писал ранее, AppleScript очень простой к пониманию язык, поэтому ещё одно «описание по учебнику» – это скучное занятие. Давайте лучше сразу перейдём к примерам? Это первый пример кода:
-- это комментарий в одну строку -- он выделяется двумя дефисами (* это тоже комментарий, но его можно использовать в несколько строк *)
Такими вставками я буду комментировать происходящее в скрипте. Комментарии, как вы поняли, не воспринимаются как код и при компиляции/исполнении игнорируются, а для нас это очень удобный вариант не заблудиться в строках кода. Теперь рассморим пример «скрытного» или «фонового» выполнения какого-либо действия, например заставим AppleScript говорить 🙂 Вставьте в Редактор AppleScript данную строчку:
say "Hello. I'm AppleScript." using "Vicki"
А теперь нажмите кнопку «Запустить». То есть в данном примере выполняется действие в фоновом режиме и при этом сценарий ни как не взаимодействует с пользователем. Что интересно, аналогичную команду можно выполнить через Терминал:
say -v Vicki "Hello. I'm AppleScript."
А теперь ещё вот такой финт. Вставляем данную строку в редактор AppleScript:
do shell script "say -v Vicki \"Hello. I'm AppleScript.\""
И снова нажимаем «Запустить». Происходит аналогичное двум первым действие, но данный пример наглядно показывает как в AppleScript можно интегрировать терминальные команды (обратите внимание, что в констркукции из кавычек я использовал экранированные обратным слешем других кавычек, пренадлежащих не AppleScript, а bash: "\"\""
– это необходимое условие иначе будет ошибка). Данная возможность нам ещё не раз пригодиться. Теперь давайте разберём пример взаимодействия AppleScript с пользователем. Вставляем в редактор такой код:
tell application "Finder" to display dialog ¬ "А это просто тестовое сообщение ;)" with icon 1 ¬ with title "Я заголовок окна" buttons {"Ну ОК"} default button 1 cancel button 1
Ну и запускаем его. Ну как? Теперь разберём по косточкам этот кусок «яблочного» кода:
- tell application “Finder” to – сказать «Файндеру» что… (вместо Finder может выступать любое приложение, например тот же Twitter, главное чтоб это приложение присутствовало в системе);
- display dialog “текст”– показать диалоговое окно с текстом что находится в кавычках, а далее опционально:
- with icon X – иконка окна, где X – идентификатор иконки: 1 – иконка приложения, 2 – иконка «Внимание» и так далее (цифрами можно подбирать иконки);
- with title “заголовок окна” – текст заголовка окна;
- buttons {“Кнопка_1″,”Кнопка_2″,…,”Кнопка_N”} – кнопки диалогового окна;
- default button X – кнопка выбранная по-умолчанию, где X – номер кнопки по-порядку;
- cancel button X – кнопка оповещающая сценарий о завершении работы (Отмена).
Теперь свяжем диалоговое окно с каким либо действием:
tell application "Finder" to display dialog ¬ "Привет, я Vicki и я умею говорить. Хочешь послушать?" with icon 1 ¬ with title "Vicki приветствует!" buttons {"Хочу", "Неа"} ¬ default button 1 cancel button 2 if button returned of result = "Хочу" then say "Hello. I'm Vicki and I like MacDaily." using "Vicki" end if
Тут уже появилась классическая конструкция if…end if. Собственно, последнюю конструкцию:
if button returned of result = "Хочу" then say "Hello. I'm Vicki and I like MacDaily." using "Vicki" end if
Можно интерпретировать как: если была нажата кнопка “Хочу” нужно выполнить действие лежащее в конструкции if тут_действие_или_несколько_действий end if. Конструкции if…end if могут быть и более сложные, например:
tell application "Finder" to display dialog ¬ "Привет, я Vicki и я умею говорить. Хочешь послушать?" with icon 1 ¬ with title "Vicki приветствует!" buttons {"Хочу", "Неа"} ¬ default button 1 if button returned of result = "Хочу" then say "Hello. I'm Vicki and I like MacDaily." using "Vicki" else say "Nu ee ne nado..." using "Vicki" end if
Ну это всё баловство 🙂 Давайте разберём что-то более серьёзное? – А давайте! Как то ранее я сделал мини-программулину на bash, которая позволяла включить или выключить отображение скрытых папок и файлов. Работает она и по сей день отлично и со своей задачей справляется на все 100%, но так как она создана на основе bash-скрипта, то ни о каком пользовательском интерфейсе не может быть и речи, работает всё «на мышу». Сегодня я хочу исправиться и представить новую её интерпритацию, на этот раз на AppleScript. Совместим приятное с полезным (теорию с практикой):
on run -- при запуске приложения через двойной клик try (* Используем знакомую терминальную команду для присвоения переменной visiblesate текущее положение дел с отображением скрытых файлов и папок. То есть данная команда должна присвоить переменной visiblesate значение FALSE или TRUE *) set visiblesate to do shell script "defaults read com.apple.finder AppleShowAllFiles" on error -- при ошибке... (* Часто по-умолчанию параметр AppleShowAllFiles в com.apple.finder.plist вообще отсутствует, что равносильно значению FALSE - то есть файлы и папки скрыты. Но при отсутствии данного ключа будет выдаваться ошибка и работа скрипта будет нарушена. Чтоб этого не происходило мы указали параметр on error - то есть при ошибке…принудительно присвоить переменной visiblesate значение FALSE *) set visiblesate to "FALSE" end try if visiblesate = "FALSE" then -- если файлы скрыты, то... -- говорим "Файндеру показать окно с такими-то кнопками и таким-то текстом" tell application "Finder" to display dialog ¬ "В данный момент все системные файлы и папки скрыты. Показать их?" with icon 1 ¬ with title "Показать?" buttons {"Показать", "Отмена"} default button 1 cancel button 2 -- если будет нажата кнопка "Показать", то выполняем две команды: if button returned of result = "Показать" then -- вносим значение TRUE в com.apple.finder.plist do shell script "defaults write com.apple.finder AppleShowAllFiles TRUE" -- перезагружаем Finder чтоб изменения всупили в силу do shell script "killall Finder" end if -- завершаем процедуру -- если же файлы отображаются, то... else if visiblesate = "TRUE" then -- говорим "Файндеру показать окно с такими-то кнопками и таким-то текстом" tell application "Finder" to display dialog ¬ "В данный момент все системные файлы и папки отображаются. Скрыть их?" with icon 1 ¬ with title "Скрыть?" buttons {"Скрыть", "Отмена"} default button 1 cancel button 2 -- если будет нажата кнопка "Скрыть", то выполняем две команды: if button returned of result = "Скрыть" then -- вносим значение FALSE в com.apple.finder.plist do shell script "defaults write com.apple.finder AppleShowAllFiles FALSE" -- перезагружаем Finder чтоб изменения всупили в силу do shell script "killall Finder" end if end if -- завершаем процедуру end run -- конец работы
Теперь нажмём кнопку «Запустить» в Редакторе AppleScript чтоб убедиться, что мы не допустили ошибок, ну и чтоб проверить работоспособность сценария. Если всё ОК, то в Редакторе AppleScript нажимаем Файл > Экспортировать… и выбираем Формат файла: программа, сохраняем на Рабочий стол. Всё! Мы получили готовую программку для скрытия и отображения скрытых/системных файлов и папок. Удобно же? Это приложение потом можно привести в «человеческий вид»: изменить иконку, добавить копирайты в файл Info.plist, но это уже тема для отдельной заметки. В общем-то это примитивный такой сценарий, но он хорошо и наглядно показывает возможности AppleScript.
Если данная тема вам интересна – оставляйте комментарии. В следующих заметках я буду приводить другие интересные и полезные примеры.
Я когда-то писал эмулятор Brainfuck на AppleScript: http://bolknote.ru/2011/07/01/~3307/.
Класс! Отличное занятие для 4-х ночи 😀
В Горном Льве вместо TRUE и FALSE стоит использовать YES и NO, в противном случае shell-скрипт будет постоянно глючить / не отрабатывать.
А вы попробуйте 😉 Я же не с потолка писал 🙂 И вообще обычно Mac OS X интерпреирует значения YES = TRUE = 1 = bool TRUE, и NO = FALSE = 0 = bool FALSE. Так что, в принципе, без разницы какое значение использовать, но «Горный Лев» «предпочитает» значение или «стринговое» TRUE/FALSE:
или «булейное» TRUE/FALSE:
Пробую создать скрипт для подключения к устройствам через usb to serial адаптер,
подскажите как обрабатывать сообщения терминала?
Нужно чтобы когда терминал возвращает ошибку “Cannot exec ‘/dev/cu.usbserial’: No such file or directory” then display dialog” выводило диалог, что устройство не найдена и по кнопке OK закрывало окно терминала.
Вопрос: Какого открывается 4 окна терминала? Где то я напортачил с вызовами его
как обработать возвращаемые ошибки терминала?
Ахахах!
Разобрался!
Выкладываю мож кому то пригодится:
Не успел проверить и отписаться 🙂 Рад что сам во всём разобрался 😉 Пример интересный и полезный, думаю найдутся «маководы» которым пригодится данное решение. Спасибо!
помогите, очень нужно написать простой скрипт при запуске которого стирается корзина.
tell application “Finder”
empty trash
end tell
Не справляется с задачей требует подверждения задания доп меню, нужно когда запускает прогу чтобы все стирал безоговорочно.
Под какой версией OS X вы сидите? Под OS X 10.9.X всё работает как нужно.
10.10 он просит подверждения.
http://1-pack.ru/trash.png
Уж как только не делал.
пошел на хитрость но уперся в новую проблему
tell application “Terminal”
do script “sudo rm -rf ~/.Trash/*
PASWW
”
end tell
где pasww – пароль админа, но теперь заметил что удаляет только файлы главного диска и сторонние диски не чистит. Что делать посоветуйте
Я когда то написал программу под OS X: ARO App store мой магазин он качает с сайта ARO.Store.OS.X.Apple.com это хостинг на котором залиты программы мои.Он не работает (сайт) это всего лишь чистый хостинг без движка.
Спасибо! Ура, я сделал команду автоматического удаления кеш папок!
Не за что 🙂 Поздравляю!
Добрый день!
Написал такой скрипт:
on idle
set wifi to do shell script “networksetup -getairportpower en1”
if wifi is “Wi-Fi Power (en1): Off” then
do shell script “networksetup -setairportpower en1 on”
end if
return 6
end idle
В настройках разрешил этой программе управлять компьютером и добавил в “объекты входа”, чтобы запускалась автоматически.
Так и есть – запускается. НО с предварительным окошком с кнопками “Завершить” и “Запустить”. Пока не нажмешь “Запустить”, не запустится. А значит, вся польза автозапуска насмарку.
Подскажите, pls, как решить вопрос?
Здравствуйте! Спасибо за статью. Попробовал – всё получилось.
Есть вопрос.
При написании программ, как можно задавать им версии?
поставил пароль на прошивку через терминал.
В утилитах были строки, не знаю как они называются…
взял слово – ****** LOG в начале строки, а потом забыл что за слово вместо ******..
Рядом нету макбука, не могу повторить на другом компе просмотреть эти записи чтобы вспомнить..