0

I have a shell script which sucessfully redirects all output to a log file and stdout (console) at the same time. However, when it exits it seems to wait for some user input from the keyboard (experimentally, any key seems to work)... So, I run the script, see the output, it exits and I have to hit e.g. the spacebar before the terminal prompt re-appears. Typing echo $? then gives the correct exit code.

The basics of the script are:

#!/bin/bash
LOG="./test.log"
rm -f $LOG
exec > >(tee $LOG) 2>&1
if [[ "$1" = "T" ]]; then
 echo "twas true..."
 exit 0
else
 echo "twas false..."
 exit 100
fi

Any help appreciated... not only do I not want to hit the spacebar but I would like to understand what is going on?

Amendment: it appears that I have to hit enter to get the terminal prompt back. From my limited experience using the ps command it would seem that my script has terminated and the bash shell is in the interruptible sleep state S. It would appear that maybe the terminal prompt output has been consumed or incorrectly redirected? I cannot see why...

3

1 Answer 1

0

I can reproduce your issue on my machine. I see that $PS1 is printed at the moment of tee $LOG execution, but not after script end. After execution of script the command prompt is empty, but you actually can type your next command and it will be executed.

That looks like Process substituion >() runs tee in background. Then exec redirects all the output to that background process. But tee from background is still printing its output to the terminal. You can see something like this if you run syslog | tee&

At the moment when all shell output came to background process tee, bash printed a command prompt $PS1 meaning that you are already can enter new commands. And only after command prompt was printed, your echo command printed its output to background process tee and then tee printed it to the terminal.

It is as if you ran your whole script background

That's approximately how I see why your command prompt was not printed after whole script execution. Like echo "twas true..." | tee $LOG&. Here & means "run preceding command in background".

Try the following code. It will do the same but without that issue.

#!/bin/bash
LOG="./test.log"
rm -f $LOG
{
    if [[ "$1" = "T" ]]; then
     echo "twas true..."
     exit 0
    else
     echo "twas false..."
     exit 100
    fi
} | tee $LOG 2>&1

Also. By default tee rewrites file so it looks like rm -f $LOG is not needed.

1

You must log in to answer this question.

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