Redirecting in Bash can be tricky. But in order to log the output of shell commands it is sometimes necessary. Sometimes it is also necessary to add some time stamps in front of the output. And sometimes it is even necessary to save the original file descriptors. The following example shows how to do all of that.
#! /bin/bash stamp () { local LINE while IFS='' read -r LINE; do echo "$(date '+%Y-%m-%d %H:%M:%S,%N %z') $$ $LINE" done } exec {STDOUT}>&1 exec {STDERR}>&2 exec 2> >(exec {STDOUT}>&-; exec {STDERR}>&-; exec &>> stderr.log; stamp) exec > >(exec {STDOUT}>&-; exec {STDERR}>&-; exec >> stdout.log; stamp) for n in $(seq 3); do echo loop $n >&$STDOUT echo o$n echo e$n >&2 done
Some best practices followed in the code are:
- Declare local variables as local.
- Use named file descriptors to avoid collisions.
- Close unused file descriptors in sub shells.
First I tied to solve my problem with the answers given at Stackexchange. But the answers where not elaborated enough for my needs. So I wrote the above answer.
BTW this is a nice overview for the different ways to redirect in Bash.
Keine Kommentare:
Kommentar veröffentlichen