頑張る調整次のコンテンツを含むスクリプトを使用してください。
# first portion of script
# ...
exec > >(tee -ia $OUT)
# ...
# second portion of script
このスクリプトの問題は、stdout
(私の端末)に多くの出力を生成することです。スクリプト作成者には、端末出力を削除するオプションは含まれていません。私オプションを削除stdout
し、ファイルからのみ出力を取得します$OUT
。
私が試したことは次のとおりです。
TERM_OPT="OFF"
# first portion of script
# ...
if [ $TERM_OPT != "OFF" ]; then
exec > >(tee -ia $OUT)
else {
# ...
# second portion of script
} > $OUT
fi
うまくいくようですが、目的はわかりません。大きな括弧 {}
この文脈では、グループコマンドのGNU部分(良い);
説明リストの後にはセミコロンが必要です。しかし、追加したり;
削除したりしても違いはないようです。()
中かっこの代わりにかっこを使うべきかどうか疑問に思います。ただし、これを行うと、すべての内容が()
サブシェルで実行されます。他人の台本だからあまり気にしないのに&サブシェルそれが何を意味するのか明確ではありません(試してみたことはありません)。
私が試したもう一つのことのように見えるハッキングですが、他の人がそれを使っているという内容を読んで、うまくいくようです。
TERM_OPT="OFF"
# first portion of script
# ...
if [ $TERM_OPT != "OFF" ]; then
exec > >(tee -ia $OUT)
else
exec > >(tee -ia $OUT 1> /dev/null)
fi
# ...
# second portion of script
これはもっと目立つので好きです。独立しかし、これは考慮する価値がありません。
質問は次のとおりです。 これを行う正しい方法は何ですか?つまり、正しい方法が何であるか退会exec > >(tee -ia $OUT)
?これらの解決策の1つが他のものよりも優れていますか?それとも全く違うことをする必要がありますか?
答え1
ただ$OUT
一時停止モードでファイルにリダイレクトする方がa
はるかに簡単です。
case $TERM_OPT in
(OFF) exec >> "$OUT";;
(*) exec > >(tee -ia -- "$OUT")
esac
シェルは終了を待たないため、スクリプトが完了した後も何かが出力され続けることtee
がわかります。tee
$ bash -c 'exec > >(tee -ia -- file); echo A'; echo B; sleep 1
B
A
A
B以降の出力を見てください。
この問題を解決するには、次を追加できます。
if [ "$TERM_OPT" != OFF ]; then
exec > /dev/null # closes the pipe to tee which should cause tee
# to see EOF on input and exit
wait # waits for all asynchronous tasks including tee
fi
スクリプトの終わりまたはEXIT
トラップにあります。
別のオプション(shでも機能)は、スクリプト全体をmain
関数に入れて、次のことです。
#! /bin/sh -
main() {
# your script here
}
case $TERM_OPT in
(OFF) main "$@" >> "$OUT";;
(*) main "$@" | tee -ia -- "$OUT"
esac
答え2
ファイルに追加するためにstdoutをリダイレクトし、端末に出力コピーを保持したくない場合は、次の手順を実行します。
exec >> "$OUT"
唯一の目的tee
は、1つのストリームを複数のストリームにコピーすることであるため、出力を1つの場所に配置したい場合は必要ありません。確かに作業することができtee -ia "$OUT" > /dev/null
ますが、それは少し愚かなことです。他のコピーを破棄するために、まだ出力をコピーします。
{}
この場合、中かっこを使用することは不明です。
中括弧にはセミコロンまたは改行文字が必要です。実際、マニュアルには次のように記載されています。「リストの後にはセミコロン(または改行)が必要です。」どちらの場合も、括弧は必要ありません。
サブシェルの意味は、サブシェルがシェルの独立したコピーで実行され、サブシェルのすべての変更が外部で表示されないことです。サブシェルの終わりにスクリプトも終了すると、あまり意味がありません。サブシェルが行うことは、不要なプロセスを開始することだけです。
私は次のようなものを選択します。
if [ "$TERM_OPT" != "OFF" ]; then
exec > >(tee -ia -- "$OUT")
else
exec >> "$OUT"
fi