Want to log all stdout
and stderr
to seperate files and add timestamp to each line.
Tried the following, which works but is missing timestamps.
#!/bin/bash
debug_file=./stdout.log
error_file=./stderr.log
exec > >(tee -a "$debug_file") 2> >(tee -a "$error_file")
echo "hello"
echo "hello world"
this-will-fail
and-so-will-this
Adding timestamps. (Only want timestamps prefixed to log output.)
#!/bin/bash
debug_file=./stdout.log
error_file=./stderr.log
log () {
file=$1; shift
while read -r line; do
printf '%(%s)T %s\n' -1 "$line"
done >> "$file"
}
exec > >(tee >(log "$debug_file")) 2> >(tee >(log "$error_file"))
echo "hello"
echo "hello world"
this-will-fail
and-so-will-this
The latter adds timestamps to the logs but it also has the chance of messing up my terminal window. Reproducing this behavior was not straight forward, it only happend every now and then. I suspect it has to with the subroutine/buffer still having output flowing through it.
Examples of the script messing up my terminal.
# expected/desired behavior
user@system:~ ./log_test
hello
hello world
./log_test: line x: this-will-fail: command not found
./log_test: line x: and-so-will-this: command not found
user@system:~ # <-- cursor blinks here
# erroneous behavior
user@system:~ ./log_test
hello
hello world
user@system:~ ./log_test: line x: this-will-fail: command not found
./log_test: line x: and-so-will-this: command not found
# <-- cursor blinks here
# erroneous behavior
user@system:~ ./log_test
hello
hello world
./log_test: line x: this-will-fail: command not found
user@system:~
./log_test: line x: and-so-will-this: command not found
# <-- cursor blinks here
# erroneous behavior
user@system:~ ./log_test
hello
hello world
user@system:~
./log_test: line x: this-will-fail: command not found
./log_test: line x: and-so-will-this: command not found
# <-- cursor blinks here
For funs I put a sleep 2
at the end of the script to see what would happen and the problem never occurred again.
Hopefully someone knows the answer or can point me in the right derection.
Thanks
Edit
Judging from another question answered by Charles Duffy, what I'm trying to achieve is not really possible in bash. Separately redirecting and recombining stderr/stdout without losing ordering