4

I have a peculiar case here which can be summed up as follows:

I want the entire error/stdout messages to be redirected to a file from my script but also there is one particular line which i want to redirect to terminal and also redirect that to the file.

This is the code:

exec &>test.log
echo "Check if this line is going to test.log"
echo "This should go to stderr" >> /dev/stderr

Now the last line should go to both stderr and test.log.

Can this be achieved somehow in bash ?

Subhayan Bhattacharya
  • 5,407
  • 7
  • 42
  • 60
  • Refer https://stackoverflow.com/questions/25474854/after-using-exec-1file-how-can-i-stop-this-redirection-of-the-stdout-to-file – Kaushik Nayak Sep 06 '17 at 08:14
  • Can I withdraw my duplicate flag? The post I linked to only has half of what he needs to answer the question, so it is not really a duplicate. – Basya Sep 06 '17 at 09:56
  • OK, I deleted the comment about the duplicate. I hoped that removed the flag as well. – Basya Sep 06 '17 at 09:57
  • Actually the flag was still there, but now that i nominated a different duplicate, your proposed duplicate information is gone. If your proposed duplicate was useful, it can be added to the "already has an answer here" box (just let me know). – tripleee Sep 06 '17 at 10:04
  • @tripleee: this question is not a duplicate of that one. The need for "tee" is the same; initially I proposed that solution. But it did not solve his problem, because his script has the exec call at the beginning, so stderr is already redirected to the file. So "tee" just overwrites the file with the last line; nothing is visible in the console and earlier entries in the file are lost. Two more things were needed (the proper handling of exec for his case) and the "-a" option for tee. Without all three things ("tee", "-a", and proper exec handling for his case) he does not have a solution. – Basya Sep 06 '17 at 17:36

1 Answers1

1

Yes, the tee command allows you to direct output to one or more files, as well as stdout.

As you pointed out in a comment, this doesn't work by itself because of the exec command.

This should do what you want:

exec 3>&1 1>test.log
echo "Check if this line is going to test.log"
exec 1>&3 3>&-
echo "Maybe this should go to stderr" | tee -a test.log >> /dev/stderr

I got the information about the way to restore stderr by properly setting up the original exec, from here, and combined it with tee.

Basya
  • 1,477
  • 1
  • 12
  • 22
  • Still nothing is coming out to the terminal , i guess that is because i have already added exec at the beginning. Is there any way to disable exec just before the message ? – Subhayan Bhattacharya Sep 06 '17 at 07:42
  • I don't think you can "disable" exec. It has redirected the file descriptors for the current process. With "tee", the output is redirected to test.log and stderr -- but you have changed stderr and stdout to go to a file. I would expect, actually, that with "tee" sending the output to the file, and stderr redirected to the file, that you would see this line twice in the file. In any case, you have redirected stderr (and stdout), so the line does go to stderr, but that has been redirected to the file. – Basya Sep 06 '17 at 09:23
  • Take a look at https://stackoverflow.com/questions/25474854/after-using-exec-1file-how-can-i-stop-this-redirection-of-the-stdout-to-file – Basya Sep 06 '17 at 09:31
  • OK, I think I have it working. I edited the answer. Note that you must use "-a" with "tee" or it overwrites the file. – Basya Sep 06 '17 at 09:52