Stack Exchange Network

Stack Exchange network consists of 175 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Visit Stack Exchange
3 thanks richvdh
source | link

You can do:

: > log # empty log file if necessary
{ { {

  ...the script

} 3>&- | tee -a log >&3 3>&-
exit "${PIPESTATUS[0]}"
} 2>&1 | tee -a log >&2 3>&-
} 3>&1
exit "${PIPESTATUS[0]}"

You could also write it as:

: > log # empty log file if necessary
exec 2> >(tee -a log >&2) > >(tee -a log)

...the script

But because bash is not waiting for those processes started with >(...), that has the nasty effect of sometimes outputting something to the terminal after the command has returned which can have even nastier effects (like silently discarding that output) if the terminal "tostop" attribute is on.

In any case, by making stdout a pipe in both solutions, and because two commands independently output the output and error messages, this will affect output buffering and the order the output and error messages are displayed.

You can do:

: > log # empty log file if necessary
{ { {

  ...the script

} 3>&- | tee -a log >&3 3>&-
exit "${PIPESTATUS[0]}"
} 2>&1 | tee -a log 3>&-
} 3>&1
exit "${PIPESTATUS[0]}"

You could also write it as:

: > log # empty log file if necessary
exec 2> >(tee -a log >&2) > >(tee -a log)

...the script

But because bash is not waiting for those processes started with >(...), that has the nasty effect of sometimes outputting something to the terminal after the command has returned which can have even nastier effects (like silently discarding that output) if the terminal "tostop" attribute is on.

In any case, by making stdout a pipe in both solutions, and because two commands independently output the output and error messages, this will affect output buffering and the order the output and error messages are displayed.

You can do:

: > log # empty log file if necessary
{ { {

  ...the script

} 3>&- | tee -a log >&3 3>&-
exit "${PIPESTATUS[0]}"
} 2>&1 | tee -a log >&2 3>&-
} 3>&1
exit "${PIPESTATUS[0]}"

You could also write it as:

: > log # empty log file if necessary
exec 2> >(tee -a log >&2) > >(tee -a log)

...the script

But because bash is not waiting for those processes started with >(...), that has the nasty effect of sometimes outputting something to the terminal after the command has returned which can have even nastier effects (like silently discarding that output) if the terminal "tostop" attribute is on.

In any case, by making stdout a pipe in both solutions, and because two commands independently output the output and error messages, this will affect output buffering and the order the output and error messages are displayed.

2 edited body
source | link

You can do:

: > log # empty log file if necessary
{ { {

  ...the script

} 3>&- | tee -a log >&3 3>&-
exit "${PIPESTATUS[0]}"
} 2>&1 | tee -a log 3>&-
} 3>&1
exit "${PIPESTATUS[@]PIPESTATUS[0]}"

You could also write it as:

: > log # empty log file if necessary
exec 2> >(tee -a log >&2) > >(tee -a log)

...the script

But because bash is not waiting for those processes started with >(...), that has the nasty effect of sometimes outputting something to the terminal after the command has returned which can have even nastier effects (like silently discarding that output) if the terminal "tostop" attribute is on.

In any case, by making stdout a pipe in both solutions, and because two commands independently output the output and error messages, this will affect output buffering and the order the output and error messages are displayed.

You can do:

: > log # empty log file if necessary
{ { {

  ...the script

} 3>&- | tee -a log >&3 3>&-
exit "${PIPESTATUS[0]}"
} 2>&1 | tee -a log 3>&-
} 3>&1
exit "${PIPESTATUS[@]}"

You could also write it as:

: > log # empty log file if necessary
exec 2> >(tee -a log >&2) > >(tee -a log)

...the script

But because bash is not waiting for those processes started with >(...), that has the nasty effect of sometimes outputting something to the terminal after the command has returned which can have even nastier effects (like silently discarding that output) if the terminal "tostop" attribute is on.

In any case, by making stdout a pipe in both solutions, and because two commands independently output the output and error messages, this will affect output buffering and the order the output and error messages are displayed.

You can do:

: > log # empty log file if necessary
{ { {

  ...the script

} 3>&- | tee -a log >&3 3>&-
exit "${PIPESTATUS[0]}"
} 2>&1 | tee -a log 3>&-
} 3>&1
exit "${PIPESTATUS[0]}"

You could also write it as:

: > log # empty log file if necessary
exec 2> >(tee -a log >&2) > >(tee -a log)

...the script

But because bash is not waiting for those processes started with >(...), that has the nasty effect of sometimes outputting something to the terminal after the command has returned which can have even nastier effects (like silently discarding that output) if the terminal "tostop" attribute is on.

In any case, by making stdout a pipe in both solutions, and because two commands independently output the output and error messages, this will affect output buffering and the order the output and error messages are displayed.

1
source | link

You can do:

: > log # empty log file if necessary
{ { {

  ...the script

} 3>&- | tee -a log >&3 3>&-
exit "${PIPESTATUS[0]}"
} 2>&1 | tee -a log 3>&-
} 3>&1
exit "${PIPESTATUS[@]}"

You could also write it as:

: > log # empty log file if necessary
exec 2> >(tee -a log >&2) > >(tee -a log)

...the script

But because bash is not waiting for those processes started with >(...), that has the nasty effect of sometimes outputting something to the terminal after the command has returned which can have even nastier effects (like silently discarding that output) if the terminal "tostop" attribute is on.

In any case, by making stdout a pipe in both solutions, and because two commands independently output the output and error messages, this will affect output buffering and the order the output and error messages are displayed.