5

I'm trying to learn the effect of exec > >(tee logfile) in the following code:

#!/bin/bash                                                                                                                 

exec 7>&1           # save stdout for later reset                                                                           

exec > >(tee logfile)          # point stdout to FIFO pointing to tee command?                                              
#+expect any subsequent output to stdout to be sent                                                                         
#+both to stdout and logfile.                                                                                               

# so let's send some output                                                                                                 
echo
echo howdy             # expect these strings to be sent both to terminal and                                               
echo g\'day            #+logfile                                                                                            
echo hello!

# restore stdout                                                                                                            
exec 1>&7
exec 7>&-

#check content of logfile!                                                                                                  
echo ------------
cat logfile

I'm just guessing here that exec > >(tee logfile) will redirect stdout to >(tee logfile).

Here's the output to terminal when this script is run:

--------------------

howdy
g'day
hello!

howdy
g'day
hello!

And here's the content of logfile:


howdy
g'day
hello!

It seems my attempt to redirect stdout back to terminal has no effect: exec 1>&7. Perhaps, exec 1>&7 happens AFTER logfile has been written and its content sent to terminal.

And I don't understand the output to terminal when the script is executed. I'm guessing exec > >(tee logfile) is blocked until cat logfile reads it. Then content of logfile is duplicated to terminal due to tee logfile.

Could you help me understand these points?

Thanks.

2
  • It is hard to help you. Because you have not said what you expected to happen. Feb 14, 2021 at 9:50
  • Catting logfile at the end of your script adds complexity that does not compensate by an increase in understanding. You already have echo --- that, for our purposes, show the same thing: That the stdout is dumped to the terminal.
    – Quasímodo
    Feb 14, 2021 at 12:00

2 Answers 2

6

The general form of the commmand is exec > output which causes all further output to stdout to be sent to the file "output".

This can be extended; eg exec 2> error will cause all futher output to stderr to be sent to the file "error"

Now, >(...) is a bashism that means write the output to a command; in this case the command is "tee logfile"

So we add the two together.

exec > >(tee logfile) means "write all further output to the command tee logfile".

Which means that all future output will be sent to the screen and (via tee) to the file "logfile"

3
  • 1
    >(command) does not mean "write the output to a command". It causes no redirection. It creates a pipe and connects it to the input of the command, and returns a file-name of the input of the pipe. Therefore > >(command) is almost equivalent to |. But I don't think that | will work here. Feb 14, 2021 at 9:55
  • I fail to see how this addresses the asker's concerns. Tee writes to stdout, right? But now stdout is a FIFO to tee. This would generate non-trivial behavior, so I'm must be missing something here because tee does write to the terminal, but I can't find the answer here. By the way, there seems to be some concurrency factor playing here: The prompt is sometimes printed before the whole output of the script has been written to the terminal (can you reproduce it?). If I put a sleep or wait before echo the prompt seems to always show only after the script has been terminated.
    – Quasímodo
    Feb 14, 2021 at 12:07
  • No; stdin is a FIFO to tee 'cos it's >(...). The more normally seen <(...) would make stdout point to the FIFO. Feb 14, 2021 at 17:51
-1

I understand now.

$ exec 7>&1
$ exec > >(tee logfile)
$ ls -l /proc/self/fd
fd/     fdinfo/ 
logan@logan-mainPC:~/my-test/learning-process-substitution$ ls -l /proc/self/fd
total 0
lrwx------ 1 logan logan 64 Feb 14 15:40 0 -> /dev/pts/0
l-wx------ 1 logan logan 64 Feb 14 15:40 1 -> pipe:[9603908]
lrwx------ 1 logan logan 64 Feb 14 15:40 2 -> /dev/pts/0
lr-x------ 1 logan logan 64 Feb 14 15:40 3 -> /proc/398229/fd
lrwx------ 1 logan logan 64 Feb 14 15:40 7 -> /dev/pts/0
$ echo hi i will restore stdout now
hi i will restore stdout now
$ exec 1>&7
$ exec 7>&-
$ ls -l /proc/self/fd
total 0
lrwx------ 1 logan logan 64 Feb 14 15:41 0 -> /dev/pts/0
lrwx------ 1 logan logan 64 Feb 14 15:41 1 -> /dev/pts/0
lrwx------ 1 logan logan 64 Feb 14 15:41 2 -> /dev/pts/0
lr-x------ 1 logan logan 64 Feb 14 15:41 3 -> /proc/398237/fd
$ cat logfile 
total 0
lrwx------ 1 logan logan 64 Feb 14 15:40 0 -> /dev/pts/0
l-wx------ 1 logan logan 64 Feb 14 15:40 1 -> pipe:[9603908]
lrwx------ 1 logan logan 64 Feb 14 15:40 2 -> /dev/pts/0
lr-x------ 1 logan logan 64 Feb 14 15:40 3 -> /proc/398229/fd
lrwx------ 1 logan logan 64 Feb 14 15:40 7 -> /dev/pts/0
hi i will restore stdout now
1
  • 3
    I don't see that this is an answer. It only demonstrates that the computer knows what to do. Feb 14, 2021 at 9:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .