名前付きパイプを使用するときにゾンビプロセスを回避する方法は?

名前付きパイプを使用するときにゾンビプロセスを回避する方法は?

通常、制御演算子を使用してバックグラウンドでFIFOファイルに書き込みを実行します&。以下のようなもの。

if [ ! -p "/tmp/mysqld.init" ]; then
    mkfifo /tmp/mysqld.init
fi

echo "something" > /tmp/mysqld.init &

exec mysqld --init-file=/tmp/mysqld.init

しかし、fifoファイルを読むと、echoプロセスはゾンビプロセスになります。それを避ける方法?

ノートこのスクリプトはDockerエントリポイントスクリプトであり、適切なゾンビハンドラはありません。 Mysqldは常にpid 1を使用します。次のようになります。

  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
    1     0 mysql    S     383m  19%   0   0% mysqld --init-file=/tmp/mysqld.init
   40     0 root     R     1532   0%   1   0% top
    7     1 root     Z        0   0%   0   0% [entrypoint.sh]

おそらくtiniをdockerのinitシステムとして使用するかもしれませんが、それなしでどうすればいいですか?二重交差?

ベストアンサー1

Bourne ShellまたはBashを使用すると、名前付きtrapパイプを閉じることができます。たとえば、

#!/bin/sh
set -eu
trap 'close_fifo; echo 1>&2 "!!! Unexpected signal termination."; exit 66' HUP TERM INT STOP

LOG_PATH="/tmp/acme.log"
touch "{$LOG_PATH}"

# Setup fifo and pipe input to log file with tee
FIFO=$(mktemp -u);
mkfifo $FIFO
tee -ia "{$LOG_PATH}" < $FIFO &

# Capture tee's process ID for the wait command.
TEE_PID=$!
# Redirect the rest of the stderr and stdout to our named pipe.
exec > $FIFO 2>&1

log() { echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*"; }

close_fifo() {
    # close the stderr and stdout file descriptors.
    exec 1>&- 2>&-

    # Wait for tee to finish since now that other end of the pipe has closed.
    [ -n $TEE_PID ] && wait $TEE_PID

    rm -f $FIFO
}

main() {
  // ---
  // Main procedure here...
}

main
close_fifo

これにより、すべての信号が捕捉され、終了信号のパイプが閉じます。すべての標準出力/エラーは、名前付きパイプを使用してファイルに書き込まれます。

Fifo処理リファレンス:https://superuser.com/a/86961/252171

おすすめ記事