web-dev-qa-db-ja.com

OS X:LaunchDaemonが実行されていません:サービスを初期化できませんでした

私が作成したNode.jsスクリプトを実行するLaunchDaemonを作成するには、 Appleの見かけは単純なドキュメント を使用しました。

これが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)を実行したことを確認しました

これらのApple docsによると、これは明らかに非推奨であるcronよりもはるかに複雑に見えます。このスクリプトをスケジュールどおりに実行するには、何をする必要がありますか?

7
nickcoxdotme

Launchctlを使い始めるのは間違いなくイライラする経験になる可能性があります。私はあなたが何をすべきかを説明する記事をたくさん見つけましたが、ダウンロード可能なサンプルはほとんどありませんでした。簡単なLaunchDaemonを以下に示します。コピーして貼り付けたくない場合は、 ここからファイルをダウンロード するだけです。

注:MY_USER_NAMEをユーザー名に置き換える必要があります。plistはスクリプトを見つける必要があります。

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

最後に、間違いを犯しやすいので、LaunchDaemonをインストールするための小さなシェルスクリプトを常に記述します。 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\""
5
zekel