I am currently using the following to capture everything that goes to the terminal and throw it into a log file
exec 4<&1 5<&2 1>&2>&>(tee -a $LOG_FILE)
however, I do not want the color escape codes / interference to enter the log file. so i have something like this that sorta works
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 )
besides read waits for a carriage return, which is not ideal for some parts of the script (for example, echo -n "..." or printf without \n ).
Answer to Jonathan Leffler's question:
In the sample script 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"
The output to the terminal is as expected, and there are no color codes / interference in the log file in the log file. However, when examining test.log I do not see [READ] ... (see line 21 of test.sh ).
The log file [of my actual bash script] contains the line Log File: ... at the end of it even after closing 4 and 5 fs. I was able to solve the problem by putting sleep 1 in front of the second exec - I assume the race conditions or fd shenanigans are to blame. Unfortunately for you guys, I cannot reproduce this problem with test.sh , but I would be interested in any assumptions that everyone might have.
bash logging exec tee
Andrew
source share