LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Why doesn't tee $(tty) produce output on the current terminal? (https://www.linuxquestions.org/questions/linux-newbie-8/why-doesnt-tee-%24-tty-produce-output-on-the-current-terminal-712314/)

openSauce 03-17-2009 02:27 PM

Why doesn't tee $(tty) produce output on the current terminal?
 
This came up in another thread and I'm confused. Why does the first use of tee produce output when the second one doesn't?

Code:

~$ this_terminal=$(tty)
~$ echo hi | tee $this_terminal >/dev/null
hi
~$ echo hi | tee $(tty) >/dev/null
~$


tredegar 03-17-2009 03:32 PM

Because you have sent it to /dev/null ?
Code:

tred@vaio:~$ this_terminal=$(tty)
tred@vaio:~$ echo hi | tee $this_terminal
hi
hi
tred@vaio:~$ echo hi | tee $(tty)
hi
tred@vaio:~$


openSauce 03-17-2009 03:37 PM

Maybe I wasn't sufficiently clear: tee sends output to the files it is given as arguments, and to stdout. I would therefore expect echo hi | tee $(tty) to output "hi" twice, just as echo hi | tee $this_terminal does. The strings returned by $this_terminal and $(tty) are the same after all - I don't see why the two commands don't behave identically.

tredegar 03-17-2009 04:02 PM

Does this help:
Code:

tred@vaio:~$ this_terminal=$(tty)
tred@vaio:~$ echo hi | tee $this_terminal
hi
hi
tred@vaio:~$ echo hi | tee $(tty)
hi
tred@vaio:~$ echo $this_terminal
/dev/pts/1
tred@vaio:~$ echo hi | /dev/pts/1
bash: /dev/pts/1: Permission denied
bash: echo: write error: Broken pipe
tred@vaio:~$ echo hi > /dev/pts/1
hi
tred@vaio:~$ echo hi | tee /dev/pts/1
hi
hi
tred@vaio:~$

?

openSauce 03-17-2009 05:11 PM

Quote:

Originally Posted by tredegar (Post 3478655)
Does this help:
Code:

tred@vaio:~$ this_terminal=$(tty)
tred@vaio:~$ echo hi | tee $this_terminal
hi
hi
tred@vaio:~$ echo hi | tee $(tty)
hi
tred@vaio:~$ echo $this_terminal
/dev/pts/1
tred@vaio:~$ echo hi | /dev/pts/1
bash: /dev/pts/1: Permission denied
bash: echo: write error: Broken pipe
tred@vaio:~$ echo hi > /dev/pts/1
hi
tred@vaio:~$ echo hi | tee /dev/pts/1
hi
hi
tred@vaio:~$

?

Not really - I think the two highlighted lines should give the same output! Don't you?

almatic 03-17-2009 05:45 PM

tee takes a file (or filedescriptor) as argument, but tty is actually a command. It will not be executed but instead be interpreted as a filename. Check "ls -la". The command "echo hi | tee $(tty)" will write "hi" into a file with the name of whatever variable $tty contains. If $tty contains nothing, there will be a file without a name in your current directory.

tredegar 03-17-2009 05:48 PM

Quote:

Not really - I think the two highlighted lines should give the same output! Don't you?
Well, yes, I do now.
Basically, the commands reduce to these:
Code:

tred@vaio:~$ this_terminal=$(tty)
tred@vaio:~$ echo $this_terminal
/dev/pts/1
tred@vaio:~$ echo hi | tee /dev/pts/1
hi
hi
tred@vaio:~$ echo hi | tee $(tty)
hi
tred@vaio:~$

This really doesn't make any sense to me but it is late here, and bash can be very precise, often for good reasons, once I have understood the bigger picture.

So I am going to do a really "bad" thing, which is to send a PM to one of LQ's bash gurus to draw his attention to this thread, and maybe he'll see the light, because I am in darkness. Await developments.....

tredegar 03-17-2009 05:59 PM

I think almatic (X-post) has answered it, I'll hold off PM-ing.
Time for bed for me. Catch up later.

openSauce 03-17-2009 05:59 PM

Haha I've just noticed that
Code:

~$ echo hi | tee $(tty)
creates 3 files called "not", "a", and "tty" in my home directory, each with the contents "hi". I think I've got it - executing tty within a $(...) environment separates it from the parent terminal, so it returns "not a tty". I'm sure that could be said more precisely/accurately, but that kind of makes sense.

openSauce 03-17-2009 06:04 PM

Quote:

Originally Posted by almatic (Post 3478741)
tee takes a file (or filedescriptor) as argument, but tty is actually a command. It will not be executed but instead be interpreted as a filename. Check "ls -la". The command "echo hi | tee $(tty)" will write "hi" into a file with the name of whatever variable $tty contains. If $tty contains nothing, there will be a file without a name in your current directory.

No - tty is executed when it appears as $(tty). From the bash manpage:
Quote:

Command Substitution
Command substitution allows the output of a command to replace the command name. There are two forms:

$(command)
or
‘command‘

Bash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with
any trailing newlines deleted.
$(tty) expands to a string containing the output of tty - in this case "not a tty". It is not the same as $tty, which would indeed be a variable reference (or is it dereference?).

openSauce 03-17-2009 06:09 PM

Actually my explanation is nonsense, if it were true this_terminal=$(tty) wouldn't work. See here for the right explanation.

anindyameister 01-18-2016 07:42 AM

This is quite late, but I use the below method to print from within the pipeline while keeping the processing untouched

Code:

$ echo HELLO | tee /dev/$(ps ax | grep $$ | grep -v grep | awk '{print $2}')| wc -m

HELLO
6

I can see the output of both the full output of the first cmd as well as the output of the wc running on it.

rknichols 01-18-2016 12:25 PM

The tty command looks for the device connected to its standard input. When you run
Code:

some_command | tee $(tty)
the pipe is set up first, so the tty command sees the pipe as its standard input, hence, "not a tty".

It's a lot easier just to use /dev/tty, which is the controlling terminal for the process regardless of I/O redirections.


All times are GMT -5. The time now is 11:59 PM.