Question

I have a series of bash scripts that echo a lot of data to stdout and occasionally to stderr. There is a main bash script which then imports and/or invokes many other bash scripts.

I'm trying to implement something that will capture the output from not just the parent script, but all children scripts. I need to capture both stdout and stderr so that any issues from compilation, etc... get captured in this log file.

I'm aware of tee and of course the normal stdout redirect >... but these don't seem to work without either adding these commands to each line of every script, both parent and children. There's several thousand lines in these scripts, so adding a redirect to each line would be impractical, even using sed.

I've seen suggestions such as: Redirect stderr and stdout in a Bash script

But these require editing every line in the scripts. Forcing my users to install screen is also impractical.

UPDATE:

Forgot to mention I want the output to still display on the console as well as write to the log. The scripts take several hours to run, and the user needs to know something is happening...

Was it helpful?

Solution

You can use yourmainscript 2>&1 | tee log which will capture stdout and stderr from all imported/invoked scripts in yourmainscript while also showing it on screen.

Inside yourmainscript, you can get the same effect using:

echo "Redirecting the rest of script output to 'log'"
exec > >(tee log) 2>&1
rest of your code

To redirect just a certain section:

echo "Redirecting the next commands"
{
  cmd1
  cmd2
} > >(tee log) 2>&1
echo "Continuing as normal"
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top