This tip isn’t really new, but it is one of those things that I used to know, forgot, remembered, and am now blogging so that it will be easier to find (for me) when I finally forget it again. Besides, I was hanging out with Bex Huff earlier tonight and he told me I need to blog more and this was what popped into my head. On a side note, I would encourage everyone to seek out someone that you “know” from this internet thang when you’re traveling. Meeting in person certainly beats any “8 things” list :). I happen to be in Minneapolis this month, so I looked up Bex and also hope to find a bar or similar establishment where Billy can don the kilt 2.0 for another picture (that may be asking a lot in 31-degree temps, though).
Enough soapbox…on with the tech talk. I’ve had several occasions where I intended to capture all output from commands I put into a shell script, but somehow forgot one or bungled the output redirection of one of them about half way through the script and overwrote the log information (put “>” instead of “>>”). Anyway, this method resolves that and also captures *all* of the output from the commands in the script. The best part is that you don’t have to add all those output redirections to each command. It’s really pretty short syntax, but you have to get it right.
Here’s what you do:
### this one was tested in bash, but should work equally well in other sh-like shells.
rm -f $LOG ### important to make sure someone didn't symlink it to your db file
### save the file descriptors
### set up output streams
exec 1> $LOG
exec 2>> $LOG
### do stuff, run commands, whatever
### all the commands run here will be logged to the $LOG file
### restore the file descriptors
### commands that come here will not be logged to the $LOG
That’s it, pretty short and sweet. Hope it helps you–I know it makes for much prettier scripts and generally makes for more helpful logfiles too. If any of the scripting gurus have suggestions for improvements, please comment below or drop me an email.