6

I was recently running tail -f on a log file of a server that was running, trying to diagnose a bug, when I accidentally bumped the keyboard and typed some characters. They got mixed in with the output of the log, with no way to tell which was which. I have had similarly annoying things happen to me countless times, and I'm sure it has happened to many other people here.

So my question is this: why does the shell (or terminal, or whatever is doing it) ambiguously mix keyboard input with command output?

I am not asking for a practical solution to an immediate problem. I can maybe figure out some way to make the shell run stty -echo when a command is run and stty echo when it finishes. But I want to know the rationale behind designing the terminal like this. Is there some practical purpose? Or is it something done only for compatibility reasons, or something that wasn't given much thought at all?

  • 3
  • 2
    Since the rest of the TTY system seems like a good design, I'm guessing this feature is there on purpose, and that purpose is to allow type-ahead. PDP-11s probably took a lot of time waiting for disk or tape input, so type-ahead would have been a real benefit. – Bruce Ediger Jun 18 '15 at 19:42
  • 1
    I edited the title for clarity, but this is a really good as asked. If there is any confusion about whether it is the shell or it is the terminal, rest-assured that it is the terminal. The shell is not involved at that point. You can make the shell echo its input to stderr with set -v, though. – mikeserv Jun 18 '15 at 20:07
  • 2
    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. – Timothy Martin Jun 18 '15 at 20:17
  • 1
    See this answer: the Unix creators designed it that way and nobody has decided it's worth changing the tty i/o system to do otherwise. – Mark Plotnick Jun 18 '15 at 20:43
5

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.)

2

With zsh, if you want to disable tty device local echo for a specific command, you can do:

STTY=-echo a-specific-command

zsh will apply the specific settings (by calling stty) and restore them when the command terminates.

Of course, you'll probably only want to do that for applications that don't read from the tty device.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.