通常、制御演算子を使用してバックグラウンドで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