次のサービスを設定しました。
[Unit]
Description=SCollector
After=NetworkManager.service
[Service]
Type=simple
ExecStart=/bin/sh -c "/opt/scollector/scollector /opt/scollector/collectors || (echo '' | /usr/bin/mail -s 'scollector died' [email protected] && exit -1)"
Restart=on-failure
[Install]
WantedBy=multi-user.target
何らかの理由でプロセスがゼロ以外のシャットダウンで終了すると、コマンドはメールを送信mail
しません。これは、scollector
コマンドラインから実行または呼び出すとうまく機能します。/bin/sh
STDOUTとSTDERRをキャプチャしましたが、mail
エラーは発生しません。中には何もありませんmaillog
。
何を提供しますか?なぜ電子メールを送信しないのですか?
答え1
/usr/bin/mail
デュアルfork
デーモンを実行してsendmail
電子メールを送信します。プロセスsendmail
は再所有されているため、init
通常は元の親プロセスで発生したことに影響されません。ただし、再所有された孫が依然として元のサービスと同じcgroupにあるsystemdの場合は例外です。何かを解体すると、systemd
再所有したプロセスを含むcgroup内のすべてのプロセスが終了しますsendmail
。
コマンドmail
自体は正しく実行されましたが、sendmail
そのタスクを実行する機会がある前にsystemdによって終了しました。
KillMode
Unit
セクションで(デフォルト)を設定してprocess
この問題を解決できますcontrol-group
。これにより、systemd
直接トリガーされたプロセスのみが終了します。
面白いことは、私がこれを使用する方法で偶然発見したことですstrace
。strace
通常は何も表示されませんが、mail
使用すると突然動作し始めましたstrace -f
。strace -f
すべての子供と孤児孫が完了するまで、基本的なプロセスは維持されます。
答え2
質問者は問題を指摘しましたが、xyrソリューションはジレンマであり、xyrはダイナミクスを誤って説明しています。
このmail
コマンドは真ですいいえデュアルフォークを実行します。一度だけフォークされ、sendmail shimプロセスはその直系の子であり、何も再び親にしません。ただwaitpid()
去る前に、その子供にサービスを提供するかどうかを選択します。
sendmail shim自体も同様です。二重フォークにはなりません。一部のMTSではまったくフォークが発生しません。他のシステムでは、一度だけ分岐し、設定可能な「配信モード」オプションに依存するかどうかを選択します。
この問題を解決する2つの正しい方法があります。
mailx
ロギングと正規化オプションのセットですsendwait
。 sendmail shimサブプロセスが完了するのをmailx
待つと、非同期キューの問題は具体的に解決されます。 (残念ながら、このオプションは少なくとも1986年から存在し、mailx
SVIDに文書化されていますが、bsd-mailxにはこのオプションはありませんが、heirloom-mailxにはあります。)- まだ使用中でない場合は、同期キュー/配信モードを使用するために使用中のMTSを設定します。
- netqmailを使用している場合、何もしません。 Netqmailのsendmail shimは常にキューにあり、同期され、直接チェーンロードされ、
qmail-inject
まったくqmail-queue
分岐しません。 - Postfixを使用している場合は何もしません。 Postfixのsendmail shimは常にキューにあり同期され、一度分岐して終了
postdrop
する前に完了するのを待ちます。 - eximには
-odf
コマンドラインオプションがあります。
- netqmailを使用している場合、何もしません。 Netqmailのsendmail shimは常にキューにあり、同期され、直接チェーンロードされ、
追加読書
- "ユーティリティ:mailx:mailxの内部変数"。 シェルとユーティリティ。単一のUNIX仕様。問題7. IEEE 1003.1。 2013. グループを開きます。