Skip to content

Instantly share code, notes, and snippets.

@Drovosek01
Last active February 6, 2022 15:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Drovosek01/89f22d375cf728c168728b5b695247b7 to your computer and use it in GitHub Desktop.
Save Drovosek01/89f22d375cf728c168728b5b695247b7 to your computer and use it in GitHub Desktop.
Как сделать приложение для последовательного запуска двух приложений в macOS

Предисловие

В этой инструкции я расскажу как создать приложение для последовательного запуска нескольких программ или исполняемых файлов так, чтобы после запуска это приложение не оставалось открытым (то есть не занимало место в пенил Dock).

У меня была такая задача: По запуску моего приложения нужно запустить rlm сервер и потом запустить приложение BricsCAD. При этом программа которая запускает rlm и потом (на тот момент я не разобрался как добавлять rlm в автозапуск, но сейчас я разобрался и для BricsCAD эта инструкция уже не актуальна, по крайней мере для меня).

Я нуб в использовании bash, Apple Script и Automator. Возможно решение этой проблемы банальное и я просто неправильно формулировал запрос в гугле (тогда напишите, как правильно задать вопрос при котором в поисковой выдаче будет решение описанной выше задачи)

Решение задачи

Изначально загуглив я написал такой shell скрипт для последовательного запуска rlm и BricsCAD

#!/bin/bash
/Volumes/ShareFiles/rlm/rlm >/dev/null & /Applications/BricsCAD\ V21.app/Contents/MacOS/bricscad & sleep 0.01
exit
exit

Его можно положить в файл с расширением .command и в настройках терминала сделать так, чтобы терминал закрывал свое окно по команде exit. Как вы понимаете у такого подхода есть 2 минуса:

  1. Этот файл нельзя поместить в панель Dock
  2. Нужно менять стандартные настройки терминала (во-первых нужно не забыть изменить эту настройку в терминале иначе после запуска .command файла будет оставаться черное окно терминала, что может пугать обычных пользователей. Во-вторых кто-то реально пользуется терминалом и не хочет, что он закрывался по команде exit)

Я видел скрипт на языке Apple Script для отмотки времени и запуска одного приложения и решил свой скрипт тоже выполнять в Apple Script Editor и потом экспортировать в .app и вот какой скрипт у меня получился:

do shell script "PATH=/usr/local/bin:$PATH; /Volumes/ShareFiles/rlm/rlm >/dev/null & '/Applications/BricsCAD V21.app/Contents/MacOS/bricscad' & sleep 0.01;exit;exit"

Это решило последние 2 проблемы, но оставался один раздражающий меня нюанс - экспортированное приложение после запуска все время висело в панели Dock пока я не завершу работу BricsCAD (об этой задаче я писал в самом начале) и для решения этой проблемы я потратил больше всего времени.

2 приложения в Dock

В ходе поисков решения этой проблемы я наткнулся на эти 2 страницы, они были полезны, но не помогли решить проблему: https://stackoverflow.com/questions/10247721/on-writing-a-linux-shell-script-to-safely-detach-programs-from-a-terminal/ https://discussions.apple.com/thread/2179510

В ходе тестирования я пробовал такие версии своего Apple Script:

  1. do shell script "PATH=/usr/local/bin:$PATH; /Volumes/ShareFiles/rlm/rlm >/dev/null & '/Applications/BricsCAD V21.app/Contents/MacOS/bricscad' & sleep 0.01 &> /dev/null &"

  2. do shell script "exec /Volumes/ShareFiles/rlm/rlm &> /dev/null & '/Applications/BricsCAD V21.app/Contents/MacOS/bricscad' & sleep 0.01 &> /dev/null &"

  3. do shell script "exec /Volumes/ShareFiles/rlm/rlm & exec '/Applications/BricsCAD V21.app/Contents/MacOS/bricscad' &> /dev/null &"

Потом от своего друга я узнал, что shell скрипты можно еще выполнять в приложении Automator. Я протестировал несколько вариаций своего скрипта и вот этот вариант оказался самым оптимальным:

exec /Volumes/ShareFiles/rlm/rlm &> /dev/null & '/Applications/BricsCAD V21.app/Contents/MacOS/bricscad' & sleep 0.01 &> /dev/null &

Но с Automator тоже есть нюанс - пока работает BricsCAD вверху в панели меню будет крутится шестеренка от Automator и она пропадет только после завершения BricsCAD. Это приемлемый вариант, но не совсем идеальный (из-за шестеренки вверху), поэтому я продолжил попытки решить описанную проблему с помощью Apple Script.

Я решил использовать более нативный путь и запускать BricsCAD не с помощью его бинарного файла, а с запускать его как приложение и вот что у меня получилось:

do shell script "exec /Volumes/ShareFiles/rlm/rlm &> /dev/null & open '/Applications/BricsCAD V21.app'"

И теперь это работает как надо - после запуска экспортированного приложения оно появляется в панели Dock буквально на секунду, потом исчезает и появляется иконка приложения BricsCAD. Я немного поразмыслил и решил модифицировать старый скрипт, и в ходе экспериметнов я выяснил, что если выполнять его в Apple Script не в одну строку, а в 2, то эффект будет тот же. Вот результат:

do shell script "exec /Volumes/ShareFiles/rlm/rlm &> /dev/null &"
do shell script "exec '/Applications/BricsCAD V21.app/Contents/MacOS/bricscad' &> /dev/null &"

Либо для запуска BricsCAD использовать нативную Apple Script команду. Тогда скрипт будет выглядеть так:

do shell script "exec /Volumes/ShareFiles/rlm/rlm &> /dev/null &"
tell application "'/Applications/BricsCAD V21.app" to activate

Завершение rlm после завершения работы ключевого приложения

Следующим этапом у меня появилась если rlm нужен только для BricsCAD, то, наверное, лучше после завершения работы BricsCAD также завершать работу RLM. Это можно сделать вручную через приложение Activity Monitor, но естественно это не наш путь. Я нагуглил, что можно с помощью специальных утилит найти процессы rlm и убить их, а можно завершить работу rlm с помощью утилиты rlmutil. Вот тут есть пример использования - https://docs.arnoldrenderer.com/display/RLAG/Shutting+down+a+License+Server

./rlmutil rlmdown RLM

Но после ввода этой команды терминал ждет подтверждения от пользователя. Я нашел несколько способов решения этой проблемы. Можно выполнить ./rlmutil --help и посмотреть документацию по этой утилите и понять, что нужна нам команда это:

./rlmutil rlmdown RLM -q

Также это можно сделать с помощью

yes | ./rlmutil rlmdown RLM

или

echo y| ./rlmutil rlmdown RLM

Перепробовав несколько вариантов доработки своего скрипта я нашел вариантм при котором rlm будет завершаться после завершения работы BricsCAD. Вот то, что у меня получилось для Apple Script:

do shell script "exec /Volumes/ShareFiles/rlm/rlm &> /dev/null &"
do shell script "sleep 0.01 & '/Applications/BricsCAD V21.app/Contents/MacOS/bricscad' || /Volumes/ShareFiles/rlm/rlmutil rlmdown RLM -q &> /dev/null &"

Заключение

Я не владею навыками работы в терминале на очень очень очень базовом уровне. Надеюсь я найду когда-нибудь время, чтобы улучшить свои знания по работе с bash. Если у вы знаете как можно улучшить представленный здесь код - я не против аргументированной критики.

Вот так я решил задачу с тем, что мне нужно создать приложение для последовательного запуска двух приложений и завершения работы первого приложения после завершения работы второго приложения.

Надеюсь это кому-то поможет.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment