People usually want to see what they're typing (unless it's a password) :-)
The terminal accepts input at any time, and buffers it until an application reads it. More than that, when the tty is in cooked mode, the kernel buffers whole lines at a time and provides some rudimentary line editing functionality that allow you to kill the entire buffered line (default binding Ctrl-u and backspace. During the time that the line is being entered and edited and until you press Enter, applications reading from the terminal read nothing at all.
The tty functionality in the kernel does not and can not know if and when an application like tail
is planning to produce output on the terminal, so it would not be able to somehow... cancel (?) line editing during such times and only during such times.
Anyway, being able to prepare the next line for the shell while something else is still busy running on the terminal and the shell is not yet ready to read that command is a feature, not a bug, so I wouldn't advocate removing it. Maybe not so useful for tail
(which will never terminate on its own), but pre-typing the next command during a long-running cp
or make
(for example), and even editing that command with Ctrl-h and Ctrl-u, all before the shell gets ahold of it, is a common thing to do. Timothy Martin wrote in a comment:
It is worth mentioning that less +F somefile
provides similar functionality to tail -f somefile
except that (accidentally) typed keystrokes will not echo
to the screen.
Yeah, but less
not only prevents those characters from being echoed, but it also eats them, so they are not available to the next application that wants to read them!
Finally, there is one more reason:
In historical times (before my time!) terminals with local echo were common. That is, the terminal (usually in hardware) would echo the characters you typed locally while also sending them down the serial line. This is useful for giving the user quick feedback even if there was lots of latency over the conection to the UNIX system (think 300 baud modem dialing up a terminal server with auto-telnet to a slow UNIX system over a token ring network — or whatever).
If you have a terminal with local echo, then you want stty -echo
at all times on the UNIX server to which you are connected. The result is approximately the same as a terminak without local echo (the common kind today) and stty echo
enabled. So from that point of view, stty echo
's job is to echo charatcers immediately as soon as they are received, regardless of what software is running, in emulation of what would happen on a terminal with local echo.
(By the way, if you have a terminal with local echo, you can't hide your password.)
ssh vagrant@127.0.0.1 -p 2222 echo $PATH
Your local system's PATH
will be printed here. You should quote the variable to prevent it from being expanded by the local shell:
ssh vagrant@127.0.0.1 -p 2222 'echo $PATH'
The same applies to:
ssh vagrant@127.0.0.1 -p 2222 echo $(which brew)
As for:
ssh vagrant@127.0.0.1 -p 2222 echo test ; which brew
which brew
is run after the SSH command ends, by your local shell. That's why this didn't work:
ssh vagrant@127.0.0.1 -p 2222 /bin/sh -c "echo\ test\ \;\ which\ brew"
Side note: you don't need to do all that escaping.
The problem here might be that you're adding brew
to your PATH
in .profile
(or .bash_profile
or some similar file), which is run when a login shell is started. SSH starts a login shell only when it is run interactively, not when it's told to run a command. From man ssh
:
If command is specified, it is executed on the remote host instead of a login shell
You could try:
ssh vagrant@127.0.0.1 -p 2222 bash -lc brew
Best Answer
The commands that read
stdin
are almost all of the filter family, i.e. programs that transform a flow of text data to a transformed one.cat
,sed
,awk
,gzip
and evensh
are good examples of such "filters".The cited commands,
cp
,mv
andrm
are definitely not filters but commands that do things with the arguments passed, here files or directories.The
cd
command is similar to them, it expects an argument (or simulate a default one if not provided), and generally doesn't output anything onstdout
, although it might output something on it in some cases like when usingCDPATH
.Even if one want to create a
cd
variant that take the target directory from stdin, it wouldn't have any effect when used in a pipeline in the Bourne shell,dash
andbash
to name a few. The last component of the command being run in a subshell, the change to a new directory won't affect the current shell. e.g.:echo /tmp | cd
would work withksh93
but notbash
,dash
,zsh
,sh
, ...cd <(echo /tmp)
would work with shells supporting process substitution (at leastksh
,bash
,zsh
) but wouldn't have any significant advantage compared tocd $(echo tmp)
The only use case that might be of interest would be something like:
Finally, such a variant would need to sort out the case it was given no argument but the expected behavior is to change the directory to the users's home or it was given no argument but the expected behavior is to read the name of the target directory from stdin. As there is no reliable way to decide, this is doomed.