Skip to main content
Tried to understand what actually happens
Source Link

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 this: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.

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.

That's approximately how I see why your command prompt was not printed after whole script execution.

Try this:

#!/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.

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.

Tried to understand what actually happens
Source Link

Try this. 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 works fineif 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.

That's approximately how I see why your command prompt was not printed after whole script execution.

Try this:

#!/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.

Try this. I can reproduce your issue on my machine, but this works fine:

#!/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.

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.

That's approximately how I see why your command prompt was not printed after whole script execution.

Try this:

#!/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.

Source Link

Try this. I can reproduce your issue on my machine, but this works fine:

#!/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.