OS X: LaunchDaemon не работает: служба не может инициализироваться

10367
nickcoxdotme

Я использовал на первый взгляд простые документы 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, явно устарел. Что мне нужно сделать, чтобы этот скрипт работал по расписанию?

7
Расширение тильды не будет работать в 10.10 и выше (по крайней мере, я знаю). Используйте абсолютный путь. Ваш скрипт должен быть 755. И я думаю, что JavaScriptCore небезопасен. fd0 8 лет назад 0
Смотрите комментарий об абсолютном пути в разделе «Что я сделал». И это не должно иметь значения, если сценарий пермиссионный _verly_ разрешительный, верно? Это не сработало бы, если бы оно не было достаточно разрешительным, верно? Но, к вашему последнему пункту, если это так, мне не повезло? nickcoxdotme 8 лет назад 0
Я рекомендую вам прочитать техническую записку - TN2083. Документация отстает от постоянно меняющихся запусков. fd0 8 лет назад 0
Для любого, кто находит это, @ fd0 ссылается на [этот документ] (https://developer.apple.com/library/mac/technotes/tn2083/_index.html) nickcoxdotme 8 лет назад 2

2 ответа на вопрос

5
zekel

Getting started with launchctl can definitely be a frustrating experience. I found a lot of articles explaining what you should do but few little downloadable samples. Here is a simple LaunchDaemon that will hopefully be a good starting point. You can just download the files here if you don't feel like copying and pasting.

Note: you need to replace MY_USER_NAME with your username. The plist needs to find your script.

// 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> 

This is a simple daemon script that will append the datetime to a file on your desktop. Note: since the script is run as root, tilde (~) won't be the home directory you expect.

// 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" 

Finally, I always write a little shell script to install the LaunchDaemons since it's easy to make a mistake. Since launchctl runs your script as root it requires that script's permissions not be writeable by others, since that would essentially give them root privileges.

// ~/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\"" 
Спасибо! У меня была другая проблема, но благодаря этому примеру и фильтрации журналов в консоли на «launchd» я смог идентифицировать свою проблему как одно из разрешений: я удостоверяюсь, что plist и скрипт принадлежат пользователю root и не доступны для записи другим и убедитесь, что я запускаю launchctl через sudo. Chris Conover 8 лет назад 3
-1
Promod

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

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

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