Запуск приложения Mac OS X от имени пользователя не останавливается самостоятельно

Я создаю пакет установщика MacOS.

Для этого я использую файл сценария после установки, который запускает приложение, а затем загружает список запуска LaunchDaemon.

Вот скрипт после установки:

#!/bin/bash

cd /usr/local/TestApp
USER_NAME=$(who | head -1 | head -1 | awk '{print $1;}')
sudo -u $USER_NAME /usr/local/TestApp/Test.app/Contents/MacOS/Test -l

sudo launchctl load /Library/LaunchDaemons/com.testapp.plist

В результате приложение запускается с sudo -u $USER_NAME /usr/local/TestApp/Test.app/Contents/MacOS/Test -l команда, а затем блокирует, потому что приложение продолжает работать.

Поэтому скрипт застревает, а LaunchDaemon никогда не загружается.

Пожалуйста, дайте мне знать, что я могу сделать это в случае.

1 ответ

Решение

Если вы просто хотите запустить приложение Mac (*.app) асинхронно,

  • использование open -a с путем к каталогу пакета (оканчивающийся на .app)
  • и передать любые сквозные аргументы командной строки после --args (увидеть man open):
sudo -u $USER_NAME open -a /usr/local/TestApp/Test.app --args -l

См. Примечание внизу, надежно определяющее $USER_NAME , имя пользователя вызывающего пользователя.

Если по какой-то причине вам нужно нацелить исполняемый файл, встроенный в *.app напрямую, вы должны использовать Bash's & управляющий оператор для запуска команды в фоновом режиме:

#!/bin/bash

# Get the underlying username (see comments below).
userName="${HOME##*/}"

# Launch the app in the background, using control operator `&`
# which prevents the command from blocking.
# (Given that the installer runs the script as the root user,
# `sudo` is only needed here for impersonation.)
sudo -u "$userName" /usr/local/TestApp/Test.app/Contents/MacOS/Test -l &

# Load the daemon.
# (Given that the installer runs the script as the root user,
# `sudo` is not needed here.)
launchctl load /Library/LaunchDaemons/com.testapp.plist

Обратите внимание, что я изменил способ определения имени пользователя:

  • ${HOME##*/} извлекает последний компонент пути из $HOME путь к домашнему каталогу основного пользователя, который отражает пользователя, вызвавшего программу установки.

  • Это более надежно, чем использование who без аргументов, вывод которых может включать других пользователей.

(Как в сторону, who | head -1 | head -1 | awk '{print $1;}' можно упростить до более эффективного who | awk '{print $1; exit}).

Другие вопросы по тегам