bashスクリプトの「mail」がコマンドラインではうまく機能しますが、launchdが実行されていると機能しないのはなぜですか?

bashスクリプトの「mail」がコマンドラインではうまく機能しますが、launchdが実行されていると機能しないのはなぜですか?

これは、Big Surを実行しているiMacで行われました。 (AskDifferentに尋ねたが、誰も答えを知らない。)

このスクリプトは、Raspberry Piで実行されているNUT(Network UPS Tool)サーバーからバッテリーデータを取得するためにlaunchdによって1日1回実行されるように設定されています。

#!/bin/bash
# Shell script to query upsmon regarding ups battery status
log=/Users/mnewman/ups/ups.log
email="[email protected]"
echo `date` "UPS Check">> $log
# get UPS data from Raspsky
bat=`/usr/local/bin/upsc apcups@raspsky | \
grep -E 'battery.charge:|input.voltage:'`
# write USB data to the log
echo $bat >> $log
# send an email
echo "$bat" | /usr/bin/mail -s "UPS Status" $email
exit 0

スクリプトはコマンドラインで正しく実行されます。自動的に失敗する電子メール行を除いて、launchdで実行されます。コンソールログには何もなく、stderrには何もありません。メールが送信されませんでした。

ただし、詳細情報表示モードでmailコマンドを実行すると、次のようになります。

echo "$bat" | /usr/bin/mail -v -s "UPS Status" $email

うまくいきます。

または、電子メール行の後に別のコマンドを追加する場合:

curl -sS https://api.prowlapp.com/publicapi/add  \
        -F apikey=$apikey -F application=$(hostname) -F event="UPS"  \
        -F description="$bat"

うまくいきます。

ここで何が起こっているのかを説明できる人はいますか?

ベストアンサー1

私はこれを他の場所で学んだ。それが明らかに:

<key>AbandonProcessGroup</key><true/>

launchd plistファイルに追加する必要があります。ジョブが完了すると、launchd はジョブと同じプロセスグループ ID を持つ残りのプロセスを終了します。この設定はこの動作を無効にします。問題は、メールがメールを送信するためにサブプロセスを開始し、スクリプトの実行が完了したときにサブプロセスがまだ完了していない可能性があることです。 launchd が子プロセスを終了すると、メールは送信されません。これがOPで説明した状況で起こるものです。私の考えでは、Mailを冗長モードで実行したり、Mail行の後に別のコマンドを追加したりすると、Mailが電子メールの送信を完了するまでスクリプトを長時間アクティブに保つことができるようになります。

おすすめ記事