Linux – Redirect Temporarily STDOUT to Another File Descriptor but Still to Screen

bashlinuxredirectionshellstdout

I'm making a script that executes some commands inside, and these commands show some output on STDOUT (and STDERR as well, but that's no problem). I need that my script generates a .tar.gz file to STDOUT, so the output of some commands executed in the script also go to STDOUT and this ends with a not valid .tar.gz file in the output.

So, in short, it's possible to output the first commands to the screen (as I still want to see the output) but not via STDOUT? Also I would like to keep the STDERR untouched so only error messages appear there.

A simple example of what I mean. This would be my script:

#!/bin/bash

# the output of these commands shouldn't go to STDOUT, but still appear on screen
some_cmd foo bar
other_cmd baz

#the following command creates a tar.gz of the "whatever" folder,
#and outputs the result to STDOUT
tar zc whatever/

I've tried messing with exec and the file descriptors, but I still can't get it to work:

#!/bin/bash

# save STDOUT to #3
exec 3>&1

# the output of these commands should go to #3 and screen, but not STDOUT
some_cmd foo bar
other_cmd baz

# restore STDOUT
exec 1>&3

# the output of this command should be the only one that goes to STDOUT
tar zc whatever/

I guess I'm lacking closing STDOUT after the first exec and reopen it again or something, but I can't find the right way to do it (right now the result is the same as if I didn't add the execs

Best Answer

stdout is the screen. There isn't a separation between stdout and "the screen".

In this instance, I would just redirect stdout to stderr temporarily with 1>&2 within a subshell. This will cause the commands' output to be shown on screen but won't be in the programs stdout stream.

#!/bin/bash

# the output of these commands shouldn't go to STDOUT, but still appear on screen

# Start a subshell
(
    1>&2                # Redirect stdout to stderr
    some_cmd foo bar
    other_cmd baz
)
# At the end of the subshell, the file descriptors are 
# as they usually are (no redirection) as the subshell has exited.

#the following command creates a tar.gz of the "whatever" folder,
#and outputs the result to STDOUT
tar zc whatever/

Is there a reason you need to pipe the output of this script into something else? Typically you'd just have tar writing to a file using the -f flag or perform a redirect on the tar command only: tar zc whatever > filename.tar.gz (unless you were putting it onto a device such as a tape or using it as a form of copy).