web-dev-qa-db-ja.com

プロセスがまだ実行されているにもかかわらず、親bashスクリプトが「トラップ」を受信しない

私が実際に達成しようとしていること:

SysVinitを使用するシステムでカスタムデーモンを動作させようとしています。デーモンを呼び出すブートストラップ/etc/init.d/xyzスクリプトがすでにありますが、自動的にバックグラウンドに配置されません。これは、nginxのようなサービスの動作に似ています。バイナリバックグラウンド自体-つまり、プロセスをデーモン化するのは/etc/init.d/nginxスクリプトの責任ではないため、/opt/nginx/sbin/nginxを直接実行した場合はデーモン化/バックグラウンド実行も経験します。

問題

私の問題は、現在のメソッドを使用すると、デーモンが親プロセスで終了しないことです(これは、service xyz stopを呼び出すと終了します)。

launcher.shスクリプトを実行する親daemon.sh &スクリプトを使用しています。ただし、launcher.shを強制終了すると、trapで最善を尽くしたにもかかわらず、daemon.shは実行され続けます(単に呼び出されることはありません)。

-> launcher.sh

#!/bin/bash

function shutdown {
    # Get our process group id
    PGID=$(ps -o pgid= $$ | grep -o [0-9]*)

    echo THIS NEVER GETS CALLED!

    # Kill process group in a new process group
    setsid kill -- -$$
    exit 0
}

trap "shutdown" SIGTERM

# Run daemon in background

./daemon.sh &

->デーモン.sh

#!/bin/bash

while true
do
    sleep 1
done

実行して殺すには:

./launcher.sh

<get PID for launcher>

kill -TERM 123 # PID of launcher.sh... which _is_ still running and has its own PID.

結果:daemon.shはまだ実行中およびshutdown関数は呼び出されません-以前にecho hereをに配置してこれを確認しました機能本体。

何か案は?

EDIT:launcher.shスクリプトはdaemon launcher.shを使用して実行されています。ここで、daemonはAmazonLinuxのinit.d/functionsによって提供される関数です。ファイル(ここを参照: http://Gist.github.com/ljwagerfield/ab4aed16878dd9a8241b14bc1501392 ‌f)。

1

trapコマンドは、スクリプトが実行されている間のみ機能します。

これが通常行われる方法は、デーモンがフォークオフされると、デーモンがそのPIDをファイルに書き込むことです。次に、initスクリプトはそのファイルを使用して強制終了するプロセスを決定するか、ランチャースクリプトを呼び出してプロセスを強制終了します。

最初の例:

launcher.sh:

/path/to/daemon.sh &
echo "$!" > /var/run/xyz.pid

/etc/init.d/xyzのシンプルでややナイーブなバージョン:

# ... pull in functions or sysconfig files ...
start() {
    # ... do whatever is needed to set things up to start ...
    /path/to/launcher.sh
}
stop() {
    # ... do whatever is needed to set things up to stop ...
    kill `cat /var/run/xyz.pid`
}
# ... other functions ...

ナイーブでない起動スクリプトは、実行しているLinuxのバージョンによって異なります。 /etc/init.dの他の例を見て、これがどのように行われるかを確認することをお勧めします。

1
J Earls

2つのスクリプトにこれを実行させたい理由は私には意味がありません。 initスクリプトでdaemon.sh &を呼び出すことはできますか?または、daemonコマンドを使用することもできます。

NAME
       daemon - turns other processes into daemons

SYNOPSIS
        usage: daemon [options] [--] [cmd arg...]

トラップを使用する必要がある場合は、daemon.shでトラップを使用してクリーンシャットダウンを実行できます。これらが実際のスクリプトなのか、単なる例なのかを判断するのは困難です。

launcher.shの問題の一部は、それが終了することです...それを実行し続けるものは何もないので、あなたはそれを殺すことはできません-それはすでになくなっています。私はこれを言っているだけではありません、私は答える前に確かめるために実際にあなたのスクリプトをテストしました。スクリプトに追加された私のコメントを参照してください。

#!/bin/bash

function shutdown {
    # Get our process group id
    PGID=$(ps -o pgid= $$ | grep -o [0-9]*)

    echo THIS NEVER GETS CALLED!

    # Kill process group in a new process group
    setsid kill -- -$$
    exit 0
}

trap "shutdown" SIGTERM

# Run daemon in background *** script keeps running ***

./daemon.sh &

# It exits here
echo "Exiting... bye!"
0
Ryan Babchishin