Hacker News new | ask | show | jobs
by telotortium 3575 days ago
Shells that want to implement features like tab completion or more elaborate line editing than the basics, which only provide for deleting the last character, word, or line (using Backspace/^W/^U) need to put the terminal into raw mode when reading the user's command line so they can bypass the basic line editing that the terminal provides (called "cooked mode").

However, you can write a shell that doesn't do this. In particular, on Linux, you can experiment in dash. You'll find that the behavior is exactly the same as this article, since the terminal remains in cooked mode. In particular, if you type `l^Ds`, that will run `ls`, though you won't be able to delete the `l` anymore since that was input before the `^D`. Also, if you type `ls^D^D`, that will log out just like typing `^D` on an empty line does. Other shells have different behaviors -- for example, Bash seems to take `ls^D` to be the same as typing `ls` followed by pressing Enter.

Before any shell starts executing a program, however, it puts the terminal back in cooked mode no matter what mode it's in when at the prompt, since that's the default terminal mode expected by programs. If you want to experiment with the cooked mode line editing commands to get the behavior described in the article, you should run a command that receives standard input from the terminal (running `cat` by itself should suffice).

1 comments

I didn't realize Dash uses cooked mode. That's actually kind of surprising; every other shell I've used always uses raw mode to give them more control over line editing. Is Dash just trying to be as minimalistic as possible?
Dash is really minimalistic. In its default mode, this is the only call to ioctl it makes on standard input according to strace:

    ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
Notice that it's merely calling TCGETS and that icanon is set, which means the "canonical input" mode with the default ^W/^U keybindings is enabled. Bash disables icanon so that it can enable line editing. Interestingly, dash seems to have vi and emacs editing modes, but they don't seem to cause dash to enter raw mode, so I'm not sure they do anything.