スクリプト(予想)が返されたため、systemdサービスはエラーのため終了しました。

スクリプト(予想)が返されたため、systemdサービスはエラーのため終了しました。

多くの関連質問を広範囲に検索しましたが、実際に効果があるものが見つかりませんでした。

したがって、システムサービスを介して自動化したいシェルスクリプトがあります。スクリプト:

#!/usr/bin/env bash

SESSION="daemon"
DAEMON_WINDOW="daemon"
CLIENT_WINDOW="client"

tmux new-session -d -s $SESSION
tmux rename-window -t 0 $DAEMON_WINDOW
tmux send-keys -t $DAEMON_WINDOW 'cd $HOME/work/gastd' C-m './gastd' C-m

sleep 30

tmux new-window -t $SESSION:1 -n $CLIENT_WINDOW 
tmux send-keys -t $CLIENT_WINDOW 'gast-client' C-m

tmux attach-session -t $SESSION:1

いいですね。シェルで実行するとうまくいきます。デフォルトでは、ウィンドウでデーモンプロセスを開始します。デーモンが何かを初期化するので、待つ必要があり、スリープ後にクライアントとして2番目のウィンドウを起動します。

これでsystemdで実行すると、実際には正常に起動し、失敗して終了するようです。

理由は簡単だと思います。すべてが実行され、スクリプトが終了するので、systemdはスクリプトが終了し、サービスが存在すると仮定します。 tmuxセッションとウィンドウを終了するのは実際の問題です。

目的は、systemctl stop serviceを実行しない限り、セッションとウィンドウを永久に実行することです。

スクリプトの末尾に無限ループを追加することはできますが、ビューには適していません。

もっと良い方法がありますか?私はそれを試しましたが、Type=forkingそれも役に立たず、何らかの理由でクラッシュしました。

これは私の現在のシステムスクリプトです。

[Unit]
Description=gast daemon

[Service]
ExecStart=/home/gastuser/start-tmux-session.sh
WorkingDirectory=/home/gastuser/work/gastd
User=gastuser
StandardOutput=file:/home/gastuser/.gast/gast.log
StandardError=file:/home/gastuser/.gast/gast.log
Restart=on-failure

[Install]
WantedBy=multi-user.target

本当に広範な検索をしました。質問/回答がすでに存在する場合は申し訳ありません。

答え1

次から読む文書:

systemdの単純なサービスタイプは次のとおりです。

oneshot短時間で完了して完全に終了するサービスです。

simpleフォアグラウンドで実行されるプログラムです。したがって、systemdは起動がいつ完了したかを確認できず、すぐに起動すると仮定します。

forkingバックグラウンドジョブの実行に適したクラシック2フォークデーモンまたはプロセス。元のプロセスが終了したら、サービスの開始が完了したと仮定します。サービスは、子プロセスの実行中に実行中と見なされます。 systemdの推測が間違っている場合は、PIDファイルを提供して子プロセスを見つけることができます。

simple私はあなたが持っているものがaまたはaだと思いますforkingが、tmuxそれを使用すると台無しになります。私の考えでは、tmuxセッションは名目上デーモンが所有しているようですtmux。したがって、systemdはサービスがまだ実行されているかどうかは必ずしもわからず、サービスが早期に終了したことを宣言します。 30秒のスリープモードforkingはデフォルトのブートタイムアウトなどを超える可能性があるため、役に立たない可能性がありますoneshot

この問題を解決するには、既存の一般的なバックグラウンドタスクに変換する&か、システムにどのプロセスが自分のものであるか、起動がいつ完了するかを明示的に伝える方法を見つける必要があります。分岐したジョブの場合は、PIDファイルを設定してから、オプションを使用してsystemdにそのファイルが見つかる場所を知らせることでこれを行うことができますPIDFile=。別のオプションは、タイプのサービスを作成したり、呼び出したり、事前定義されnotifyたインターフェース名を使用してdbus直接起動できることをsystemdに通知することです。それにもかかわらず、tmuxがこれで何をするのかわかりません。sd_notifyD-Bus

答え2

努力する:

Type=oneshot

男性の場合:

oneshotは単に機能しますが、サービスマネージャは基本プロセスが終了した後にデバイスを考慮します。

関連情報