私は現在、ターミナルに送られるすべてのものをキャプチャしてログファイルにスローするために以下を使用しています
exec 4<&1 5<&2 1>&2>&>(tee -a $LOG_FILE)
ただし、カラーエスケープコード/クラッターをログファイルに入れたくありません。だから私はこのようなものを持っています
exec 4<&1 5<&2 1>&2>&>(
while read -u 0; do
#to terminal
echo "$REPLY"
#to log file (color removed)
echo "$REPLY" | sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' >> $LOG_FILE
done
unset REPLY #tidy
)
read
スクリプトの一部(例:echo -n "..."
またprintf
はなし)では理想的ではないキャリッジリターンを待機する場合を除きます\n
。
ジョナサンレフラーの答えへのフォローアップ:
サンプルスクリプトを考えるとtest.sh
:
#!/bin/bash
LOG_FILE="./test.log"
echo -n >$LOG_FILE
exec 4<&1 5<&2 1>&2>&>(tee -a >(sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' > $LOG_FILE))
##### ##### #####
# Main
echo "starting execution"
printf "\n\n"
echo "color test:"
echo -e "\033[0;31mhello \033[0;32mworld\033[0m!"
printf "\n\n"
echo -e "\033[0;36mEnvironment:\033[0m\n foo: cat\n bar: dog\n your wife: hot\n fix: A/C"
echo -n "Before we get started. Is the above information correct? "
read YES
echo -e "\n[READ] $YES" >> $LOG_FILE
YES=$(echo "$YES" | sed 's/^\s*//;s/\s*$//')
test ! "$(echo "$YES" | grep -iE '^y(es)?$')" && echo -e "\nExiting... :(" && exit
printf "\n\n"
#...some hundreds of lines of code later...
echo "Done!"
##### ##### #####
# End
exec 1<&4 4>&- 2<&5 5>&-
echo "Log File: $LOG_FILE"
端末への出力は期待どおりであり、ログファイルに必要なカラーエスケープコード/クラッターはありません。ただし、調べてみると、は表示され
test.log
ません[READ] ...
(の21行目を参照test.sh
)。[私の実際のbashスクリプトの]ログファイルには
Log File: ...
、4および5 fdsを閉じた後でも、その最後に行が含まれています。sleep 1
2番目の前にaを置くことで問題を解決することができましたexec
-競合状態またはfdshenanigansが原因であると思います。残念ながら、この問題を再現することはできませんが、test.sh
誰かが持っているかもしれない憶測に興味があります。