1

I'm writing a bash script and using the following trick to redirect standard output into a named pipe which is consumed by tee:

exec > >(tee -a $LOGFILE) 2>&1

However, when the script exits, it does not return the shell until I press enter. Is there a simple way to fix this while still using this approach?

Edit: This is the environment I'm running this in:

Centos 7 
Bash version 4.2.45

Contents of simple script called redirect.sh:

#!/bin/bash 
exec > >(tee -a /tmp/haha) 2>&1 
echo "hi there" 
exit 0

Sample session:

[root@linux-ha-1 ~]# ./redirect.sh 
[root@linux-ha-1 ~]# hi there 

[root@linux-ha-1 ~]#
rici
  • 234,347
  • 28
  • 237
  • 341
duffsterlp
  • 347
  • 1
  • 5
  • 15
  • 1
    untested: before you exit your script, turn off output: `exec 1>&- 2>&-` -- that may close the tee. – glenn jackman May 14 '15 at 13:47
  • Thanks for the comment, but it doesn't work. – duffsterlp May 14 '15 at 13:53
  • I'd suggest you run your script with `set -x` on so you can see what's going on. I don't think that stdout redirection would need you to hit enter. – glenn jackman May 14 '15 at 14:11
  • I'm assuming you mean that you don't see the shell prompt until you hit enter? But that you are actually at a prompt that you just can't see (so typing a command and hitting enter works correctly even at that point)? – Etan Reisner May 14 '15 at 14:33
  • Yes Etan, I am actually at the prompt so typing a command and hitting enter works at that point. The issue is that I'd like to see the prompt when the script exits because other folks that are running the script will have no idea that the script exited until they hit enter. – duffsterlp May 14 '15 at 14:43
  • I can't reproduce this unless I run the script in background (`&`). How are the users running it? – cdarke May 14 '15 at 15:25
  • This is on centos 7 with bash version 4.2.45 contents of simple script called redirect.sh #!/bin/bash exec > >(tee -a /tmp/haha) 2>&1; echo "hi there"; exit 0; [root@linux-ha-1 ~]# ./redirect.sh [root@linux-ha-1 ~]# hi there [root@linux-ha-1 ~]# – duffsterlp May 14 '15 at 16:29
  • 1
    I know this is horribly formatted, but I'm not going to waste my time learning SOs silly formatting rules when it should just work as WYSIWYG. – duffsterlp May 14 '15 at 16:32
  • After running redirect.sh, there is an empty line after hi there. – duffsterlp May 14 '15 at 16:38
  • @duffsterlp: You can't put well formatted code in a comment on SO, but you shouldn't do that anyway. Edit your question to include the actual script and whatever other details seem relevant. Formatting code only requires that you put four spaces at the beginning of each line. – rici May 14 '15 at 16:44

1 Answers1

1

The prompt is being printed; unfortunately, it is printed before tee's output is printed (which is why it appears before hi there in the sample output).

Since the tee process is running asynchronously, there is no guarantee that it will send its output to the console before the script terminates. What you really want to do is to close the tee process and then wait for it to terminate before exiting from the script. This cannot be done with process substitution, unfortunately, but it can be accomplished either with coprocesses (in bash 4) or using named pipes, as is explained in the answer to bash: How do I ensure termination of process substitution used with exec?

For a simpler (but unreliable) solution, close the pipes feeding the tee process (which will force it to close) and then wait a few milliseconds:

#!/bin/bash
exec 3>&1 > >(tee -a /tmp/haha) 2>&1 
echo "hi there"
exec 1>&3 2>&3
sleep 0.1
Community
  • 1
  • 1
rici
  • 234,347
  • 28
  • 237
  • 341
  • @duffsterlp: Yeah, it's not reliable. Added the sleep solution (also unreliable), but the correct solution is the one in the linked answer. Maybe I should just mark this as a duplicate and delete my answer. – rici May 15 '15 at 01:39