以下を使用して、スクリプト内のスクリプト出力をログファイルにリダイレクトできますexec
。
#!/bin/bash
exec > stdout.log 2>&1
echo hello world
less
ファイルの代わりに出力をリダイレクトできますか?頑張った
#!/bin/bash
exec > >(less) 2>&1
# output some text
for (( i=1; i <= 500; i++ )); do echo "hello world $i"; done
しかし、奇妙な方法で失敗します。プロンプトはあまり表示されませんが、端末に戻ります。
これをスクリプトの先頭に設定したいです(パラメータ、ttyなどによって条件付きで設定できます)。
ベストアンサー1
スクリプトが子less
プロセスを待つようにする必要があります。そうしないと、スクリプトが終了する前に終了し、less
突然フォアグラウンドプロセスグループの外部になり、端末からコマンドを読み取ったり端末設定を復元したりできなくなります。
また、入力が完了するまで永遠に待たないようにするには、less
スクリプトがパイプを閉じる必要があります。
これらすべてを総合すると、次のようになります。
exec > >(less) 2>&1
trap 'exec >&- 2>&-; wait' EXIT
# >&- 2>&- => close stdout and stderr => cause EOF on less' stdin
seq 1 50000
# the rest of your script
しかし、これはあまり良くなく、他のほとんどのシェルに移植可能ではなく、文書化されていない(信頼できない)bashの動作に依存します。wait
スクリプトに複数がある場合は動作せず、待機exec > >(...)
します。他のバックグラウンドプロセスはで始まります&
。
より良い考えは、無限の再帰を避けるために環境変数を使用してスクリプト自体を呼び出すことです。
if [ ! "$CALLED_MYSELF" ]; then
set -o pipefail # supported in bash, but not in all the shells
CALLED_MYSELF=1 "$0" "$@" 2>&1 | less
exit
fi
seq 1 50000
# the rest of your script