7

Я использовал на первый взгляд простые документы Apple для создания LaunchDaemon для запуска сценария Node.js, который я написал.

Вот файл plist . Это в основном копия-вставка из документов Apple, настроенная на запуск каждые 300 секунд:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.wintr.eodemail</string>
    <key>ProgramArguments</key>
    <array>
        <string>~/projects/eod_email/eod</string>
    </array>
    <key>StartInterval</key>
    <integer>300</integer>
<key>StandardOutPath</key>
    <string>/var/log/eod-email.log</string>
    <key>StandardErrorPath</key>
    <string>/var/log/eod-email.log</string>
    <key>Debug</key>
    <true/>
</dict>
</plist>

Вот ошибка, которую я получаю в /var/log/system.log:

Jul 22 10:55:52 Nick-Cox com.apple.xpc.launchd[1] (com.wintr.eodemail[7097]): Service could not initialize: 14E46: xpcproxy + 13421 [1402][7D917364-B96E-3F93-B923-A89B5BF5736D]: 0x2

Что я сделал:

  • Он имеет те же права доступа, что и остальные файлы в /Library /LaunchDaemons (-rw-r--r-- , принадлежащий пользователю root)
  • Я прочитал документы для xpc , но это не сильно помогло.
  • Я позаботился о том, чтобы скрипт Node.js был адекватно разрешающим (777) и запускался из командной строки (это так).
  • Попробовал абсолютный путь к файлу (/Users/nickcox/projects/eod_email/eod) и убедился, что я запустил launchctl unload (daemonname) и launchctl load (daemon name)

Это кажется намного более сложным, чем cron, который, по мнению тех Apple, явно устарел. Что мне нужно сделать, чтобы этот скрипт работал по расписанию?

2 ответа2

5

Начало работы с launchctl определенно может быть разочаровывающим опытом. Я нашел много статей, объясняющих, что вы должны делать, но мало маленьких загружаемых примеров. Вот простой LaunchDaemon, который, будем надеяться, станет хорошей отправной точкой. Вы можете просто скачать файлы здесь, если не хотите копировать и вставлять.

Примечание. Вам нужно заменить MY_USER_NAME своим именем пользователя. Плист должен найти ваш сценарий.

// at ~/Desktop/testdaemon/com.wintr.eodemail.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.wintr.eodemail</string>
    <key>Program</key>
    <string>/Users/MY_USER_NAME/Desktop/testdaemon/testdaemon.sh</string>
    <key>StandardErrorPath</key>
    <string>/var/log/eod-email.log</string>
    <key>StandardOutPath</key>
    <string>/var/log/eod-email.log</string>
    <key>RunAtLoad</key>
    <true/>
    <key>StartInterval</key>
    <integer>15</integer>
</dict>
</plist>

Это простой демон-скрипт, который добавит дату и время к файлу на вашем рабочем столе. Примечание: поскольку скрипт запускается от имени пользователя root, тильда (~) не будет ожидаемой вами домашней директорией.

// at ~/Desktop/testdaemon/testdaemon.sh
#!/bin/sh
home="/Users/MYUSERNAME" ## note -- this will be run as root, ~ is not your normal user
now=$(date "+%Y-%m-%d %H.%M.%S")
echo $now >> "$home/Desktop/TestFile.txt"

Наконец, я всегда пишу небольшой скрипт для установки LaunchDaemons, так как легко ошибиться. Так как launchctl запускает ваш сценарий от имени пользователя root, он требует, чтобы разрешения сценария не были доступны для записи другими, поскольку это, по сути, дало бы им привилегии root.

// ~/Desktop/testdaemon/install.sh
#!/bin/sh -e
plist_path="com.wintr.eodemail.plist"
plist_filename=$(basename "$plist_path")
install_path="/Library/LaunchDaemons/$plist_filename"

echo "installing launchctl plist: $plist_path --> $install_path"
sudo cp -f "$plist_path" "$install_path"
sudo chown root "$install_path"
sudo chmod 644 "$install_path"

sudo launchctl unload "$install_path"
sudo launchctl load "$install_path"

echo "to check if it's running, run this command: sudo launchctl list | grep wintr"
echo "to uninstall, run this command: sudo launchctl unload \"$install_path\""
-2

Было бы полезно, если бы вы могли вставить вывод launchctl list | grep 'com.wintr.eodemail' .

Также проверьте ваш файл /var/log/eod-email.log . Это может дать вам точные ошибки.

Я рекомендую установить brew cask install launchcontrol , который является графическим инструментом для launchctl, он может помочь обнаружить ошибки и устранить неполадки.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .