私はNASサーバーのsnapraidを自動化するスクリプトを実行しています。以下はオンラインで見つけたスクリプトで、Debian 9で問題なく実行されます。先週、Debian 10にアップデートしましたが、Debian 9では動作しない場所でスクリプトがクラッシュします。問題に絞り込んでコマンドを待っているようです。
テストのためにスクリプトを次のスニペットに短縮しましたが、問題が発生しているので待つ必要があると思います。
#!/bin/bash
# location of the snapraid binary
SNAPRAID_BIN="/usr/local/bin/snapraid"
# redirect all output to screen and file
> $TMP_OUTPUT
exec 3>&1 4>&2
# NOTE: Not preferred format but valid: exec &> >(tee -ia "${TMP_OUTPUT}" )
exec > >(tee -a "${TMP_OUTPUT}") 2>&1
# run the snapraid DIFF command
echo "###SnapRAID DIFF [`date`]"
$SNAPRAID_BIN diff
# wait for the above cmd to finish
wait
echo
echo "DIFF finished [`date`]"
また、何が起こっているのかを確認するためにhtopを実行しましたが、snapraidコマンドで生成されたプロセスは終了しませんでした。
waitはやるべきことをしています。しかし、この方法が以前は機能していましたが、今は機能しないのはなぜですか?
完全なスクリプトはここにあります:https://pastebin.com/gJqnz875
答え1
プロセス内の交換は、tee
標準入力からeofを受け取るか、またはいくつかのエラーが発生するまで終了しません。
EOF
そして標準入力はパイプなので、書き込み側のすべてのハンドルが閉じたときに標準入力から1つだけ取得されます。
したがって、元のstdoutとstderrを保存してからfdを閉じてコピーするwait
前に、元のファイルにリダイレクトする必要があります。new>&old
old
exec {out}>&1 {err}>&2
exec > >(tee -a output) 2>&1
...
exec >&$out 2>&$err
wait $(pgrep -P "$$")
また、最新バージョンのbashでのみプロセスの置き換えで実行されているプロセスを待っているwait
ため> >(...)
、単に親プロセスを見つけるwait $(pgrep -P "$$")
のではなく使用します。また見てくださいwait
pgrep -P
こここれと他の関連トラップについて> >(...)
。