バックグラウンドでinit.dスクリプトによって実行されるプロセスがあります。例えば:
case "$1" in
start)
/bin/myprocess &
stop)
killall myprocess
restart)
killall myprocess
/bin/myprocess &
esac
特定の条件では、myprocessが失敗して戻る場合があります。障害を検出して自動的に再起動する方法(標準)はありますか?
最も簡単な方法は、それを / etc/inittab に追加することです。これは、このようなことを行うように設計されています。
respawnプロセスが存在しない場合は、プロセスを開始します。終了を待たないでください(/ etc/inittabファイルのスキャンを続行します)。プロセスが停止したらプロセスを再起動します。プロセスが存在する場合は、何もせずに/ etc/inittabファイルのスキャンを続行します。
たとえば、次のようにできます。
# Run my stuff
myprocess:2345:respawn:/bin/myprocess
Buildrootには3つの可能なinitシステムがあるため、これを行うには3つの方法があります。
init
これにより、/etc/inittab
にエントリが追加されます。
::respawn:/bin/myprocess
BusyBox init
は、特異な/etc/inittab
形式であることに注意してください。 2番目のフィールドは意味がなく、最初のフィールドはIDではなく、デバイスのベース名です。
init
ここでも、/etc/inittab
にエントリを追加します。
myprocess:2345:respawn:/bin/myprocess
systemd
たとえば、ユニットファイルを/etc/systemd/system/myprocess.service
に書き込みます。
[Unit]
Description=My Process
[Service]
ExecStart=/bin/myprocess
Restart=always
[Install]
WantedBy=multi-user.target
これを有効にして、起動時に自動起動します。
systemctl enable myprocess.service
次のコマンドで手動で開始します。
systemctl start myprocess.service
常に同じプロセスを呼び出すループを持つサブシェルを作成するのはどうですか?
終了すると、ループの次の反復が続行され、再び開始されます。
(while true; do
/bin/myprocess
done) &
サブシェルが死んだとしても、それは終わりです。その場合の唯一の可能性は、あなたのプロセスが生きているかどうかをチェックする別のプロセス(私はそれをネクロマンサーと呼びます)を作成することです。
次のステップは、cronが停止した場合、どうなるのか疑問に思うでしょうが、ある時点で、安全を感じ、心配する必要がなくなります。
スーパーユーザーでもrootでもない場合、およびLinuxシステムにDockerがインストールされている場合は、システムの再起動時にdockerを使用してプロセスを再起動し、プロセスのdockerイメージを作成できます。
ファイル:docker-compose.yml
version: "3"
services:
lserver:
image: your_docker_image:latest
ports:
- 8080:8080 # just use 8080 as an example
restart: always # this is where your process can be guaranteed to restart
Dockerコンテナを起動するには、
docker-compose up -d
私がシステムのスーパーユーザーでない場合は、自動再起動で自分のプロセスを処理するのは簡単です。
Dockerイメージを作成する方法のサンプル例として、簡単な例を以下に示します。
ファイル:Dockerfile
FROM Alpine:3.5
RUN apk update && apk upgrade && rm -rf /var/cache/apk/*
WORKDIR /app
COPY my-process-server /app
RUN ln -s /app/my-process-server /usr/local/bin/my-process-server
EXPOSE 8080
CMD ["my-process-server"]
restarter を使用できます
start)
restarter -c /bin/myprocess &
stop)
pkill -f myprocess
新しいシステムでは、これらすべての些細な問題を解決するsystemdを使用します
私の場合、クイックフィックスとして、@ Trylksのソリューションを変更して使用し、起動していたプログラムをラップしました。綺麗な出口だけで終わらせたかった。
ほとんどのシェルで実行する必要があります:
#!/bin/sh
echo ""
echo "Use: $0 ./program"
echo ""
#eg="/usr/bin/apt update"
echo "Executing $1 ..."
EXIT_CODE=1
(while [ $EXIT_CODE -gt 0 ]; do
$1
# loops on error code: greater-than 0
EXIT_CODE=$?
done) &