2017-06-11 16 views
0

ユーザーがOS Xマシンにログインしたときにgrunt watchを実行しようとしているので、毎回手動で$ APP_ROOTディレクトリにgrunt watchを実行する必要はありません。launchd .plistファイルを使用してgrunt watchコマンドをデーモン化するにはどうすればよいですか?

私は/Library/LaunchAgents内で以下のorg.grunt.watch.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>org.grunt.watch</string> 

    <key>RunAtLoad</key> 
    <true/> 

    <key>ProgramArguments</key> 
    <array> 
     <string>/usr/local/bin/grunt-watch-launchd</string> 
    </array> 

    </dict> 
</plist> 

/usr/local/bin/grunt-watch-launchdは、私が作成したシェルスクリプトです:

#!/bin/sh 

APP_ROOT=/path/to/htdocs/app 
/usr/local/bin/daemon -- /usr/local/bin/grunt watch --gruntfile="$APP_ROOT"/Gruntfile.js > /tmp/grunt-watch-launchd.log 2>&1 

スクリプトがdaemonbrew install daemonでインストール)ユーティリティと「デーモン化を使用する必要があります"grunt watchコマンドはGruntfile.js構成をロードし、監視タスクを開始します。

/usr/local/bin/grunt-watch-launchdをCLIから手動で実行すると、すべて正常に機能します。私はdaemonps aux | grep gruntが表示され、コマンドが実行されています。 APP_ROOT内のファイルを編集すると、Gruntのwatchタスクが私のGruntfile.js内の特定のタスクをトリガーします。

しかし、要点は、launchdが私のユーザーと一緒にログインすると自動的に/usr/local/bin/grunt-watch-launchdが始まることです。問題は、私はlaunchctlを実行するとことです:

launchctl load /Library/LaunchAgents/org.grunt.watch.plist

サービスがロードされていません。または少なくともlaunchdはスクリプトを呼び出します(/tmp/grunt-watch-launchd.logが作成されているため、/tmp/grunt-watch-launchd.logは空ですが)が、デーモンプロセスが作成されていないように見えるか、何らかの形でlaunchdによって殺されました。

また、/var/log/system.logには何も表示されません。私は、sudoでlaunchctlを実行しようとする:(いずれかの方法で

Jun 11 18:22:24 antons-mbp com.apple.xpc.launchd[1] (org.grunt.watch[83009]): Service exited with abnormal code: 1 

/var/log/system.logは私に語った、sudoを使用して

daemon: fatal: refusing to execute unsafe program: /usr/local/bin/grunt (/usr/local/lib is group writable) 

sudo launchctl unload /Library/LaunchAgents/org.grunt.watch.plist && sudo launchctl load /Library/LaunchAgents/org.grunt.watch.plist

/tmp/grunt-watch-launchd.logは、次の行が含まれていますlaunchctlとsudoがある場合とない場合)、サービスが開始されていないことを確認できますd:

mymachine:~ user$ launchctl list | grep grunt 
- 0 org.grunt.watch 

ユーザーのログイン時にこのスクリプトをデーモンとして実行するには、何が問題なのですか。

ご協力いただきありがとうございます。

EDIT

: は、私は私は、Mac OS X 10.12シエラは、 npmでうなり声を設置し使用して(それが役立つ可能性がある場合)私はのMacBook Pro(13インチ、2012ミッド)を使用していますと言うことを忘れていました。

EDIT 2: 問題が見つかりました。launchdエージェントとして実行しているとき、エージェントのユーザーが自分のユーザーではないため、スクリプトはコマンドを見つけることができませんでした。したがって、127エラーが発生しました。

だから、これは本当に簡単launchdエージェントに貼り付け私のようなすべての男のためにある:

  • は常にあなたが使用するコマンドは、コマンドを起動したユーザのPATHにあることを確認してください。絶対パスを使用し、必要に応じてスクリプトの最初の行にPATH変数を設定します。 launchdは(私の場合にはエラーが何らかの理由で/var/log/system.logに表示されませんでした)スクリプトを起動したときにエラーが発生した場合、あなたが見ることができるように

  • は、ファイルにすべてのコマンドの出力をリダイレクトします。

答えて

1

私はgruntまたはdaemonユーティリティのいずれかに慣れていないんだけど、私はdaemonはlaunchdのジョブの管理方法と競合しているかなり確信しています。本質的に、あなたは、異なることをする2つの異なるデーモン作成ツールを使用しており、1つだけを選ぶ必要があります。

具体的には、私はdaemonがバックグラウンドでgruntを起動している(つまり、それをデーモン化している)と思われます。しかし、launchdは、自分が管理している仕事を監視して制御できる前景にとどまることを期待している。おそらく起こっていることは、launchdがあなたのスクリプトを起動し、スクリプトがgrunt watchをバックグラウンドで実行してから終了するということです...そしてlaunchdは、ジョブが終了し、gruntのような残りのサブプロセスを有効にクリーンアップすることを確認します。結果:実際にはgruntデーモンが実行されていません。

あなたは、バックグラウンドプロセスを殺すしないようにlaunchd伝えるためにあなたの.plistにを追加することもできますが、実際に物事にlaunchdの方法を行うと、フォアグラウンドでgruntを残す方が良いだろう。したがって、スクリプトからdaemonコマンドを削除するか、execで置き換えてください。起動時にはトップレベルのプロセスとしてgruntが実行されます(通常は実行するとシェルのサブプロセスになり、シェルはトップレベルになります)。打ち上げ中のプロセス)。

ここに他の問題があるかもしれませんが、これが修正されるまでは分かりません。

+0

ありがとうございます!私は問題を発見した、あなたは私のEDIT 2をチェックすることができます – tonix

関連する問題