Live data from Hacker News

What typing ^D does on Unix (2009)

utcc.utoronto.ca

31–40 of 162 posts

Re: What typing ^D does on Unix (2009)

#32
post #26

As a corollary, typing ^D twice on a non-empty line will also send EOF on the input, allowing you to provide a program with input not ending with \n from the command line. I knew about this behavior, but not why it worked, but this article's explanation clarifies this behavior as well. The first ^D terminates the read() call, passing the line so far, without terminating \n, to the program. The second causes read() to…

I know this article says Unix specifically, but on Linux (Ubuntu) I just tried typing `ls^D` in bash and got a terminal beep. I tried in zsh and got an autocomplete as if I'd hit tab. In ksh and fish nothing happened. I'm curious as to why there are different behaviors here?

I believe your answer is in the article: "Note that modern shells are not good examples of this, because they don't do line-buffered input; to support command line editing, they switch terminal input into an uninterpreted mode. So they get the raw ^D and can do whatever they want with it, and they can let you edit as much of the pending line as they want."

Re: What typing ^D does on Unix (2009)

#33
post #30
post #26

Earlier quoted context omitted.

I know this article says Unix specifically, but on Linux (Ubuntu) I just tried typing `ls^D` in bash and got a terminal beep. I tried in zsh and got an autocomplete as if I'd hit tab. In ksh and fish nothing happened. I'm curious as to why there are different behaviors here?

As the article explained at the end, shells put the terminal into uninterpreted mode, so ^D doesn't do anything special there. You have to be using a program (such as cat) that doesn't do this to see ^D's behavior.

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

Re: What typing ^D does on Unix (2009)

#34
post #13
post #11

Earlier quoted context omitted.

^Y will paste the cleared buffer back again

So ^U will let a partial password linger in memory longer than it needs to if you use it as suggested by the GP?

To elaborate on yebyen's answer: these shortcuts can be handled in different layers of your stack. By default, ^U will be handled by your terminal emulator, and it will only delete the buffer, it won't remember what you've deleted. However, programs can ask the terminal emulator to pass ^U through to them so they can handle it themselves. This happens if you use libeditline (or libreadline), and these libraries implement a per-application buffer.

You can test this yourself. Type some text, then ^U, then ^Y. This works because your shell uses libreadline or libeditline. Try this again in a "dumb" program like cat, or a shell without line editing like /bin/dash. ^U works, but ^Y does nothing (well, it lets you type ^Y in as much as you want).

Re: What typing ^D does on Unix (2009)

#35

Earlier quoted context omitted.

^L usually has no assigned action. $ stty -a | grep -F '^D' intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ; $ stty -a | grep -F '^L' $ Your Ctrl-L clear-and-refresh command is implemented in Bash (or rather GNU readline). There is a "reprint" action, commonly bound to ^R: $ stty -a | grep rprnt eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; It doesn't clear the screen; it just issues…

And sadly ^t doesn't do the Tenex function of a snapshot of sysstat for the current process.

Not sure what sysstat on Tenex did, but you can still use ^T on the BSDs and Mac OS X to get the wait channel and some additional stats.

Re: What typing ^D does on Unix (2009)

#36

Earlier quoted context omitted.

^L usually has no assigned action. $ stty -a | grep -F '^D' intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ; $ stty -a | grep -F '^L' $ Your Ctrl-L clear-and-refresh command is implemented in Bash (or rather GNU readline). There is a "reprint" action, commonly bound to ^R: $ stty -a | grep rprnt eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; It doesn't clear the screen; it just issues…

And sadly ^t doesn't do the Tenex function of a snapshot of sysstat for the current process.

It does on BSDs and OS X, but not on SYSV derivatives and Linux because NIH.

Re: What typing ^D does on Unix (2009)

#37
I wish articles like this would say what ^D means. I remember when I was new to Unix it took me a while to realize that I wasn't supposed to type a literal caret (^) followed by a D.

For reference it means Ctrl+D, unless you you have a strange keyboard from Sun or something.

Re: What typing ^D does on Unix (2009)

#38
post #25

^U will clear the buffer - super convenient for retrying botched passwords.

In readline, ^U will only clear from the cursor to the start of the line, leaving anything on the right. ^K is the converse. I'm not sure you are speaking about readline though. Another very useful thing I use daily is Alt-F/B, to move forward/backward in the line one word at a time. Control does the same, one letter at a time. D will delete an element instead.

I also find Ctrl-W for backspacing a word at a time useful and also Ctrl-A/E for jumping to the beginning and end of the current line.

Ctrl-L to clear the screen except the current line is also somewhat useful if you're at the bottom of the terminal screen and editing a long command line.

Somewhat less useful but neat is Alt-U which will cause the current word under the cursor to become all upper case and Alt-C which is similar but changes the first letter to upper case and the rest of the word to lower case.

Re: What typing ^D does on Unix (2009)

#39

Pressing enter then ~. will gracefully shutdown hung ssh sessions

I am amazed by the fact that I never accidentally trigger this feature.

Hah, yeah I seem to remember Ctrl-S leaving me flustered for quite a while when I first stumbled on it!

Re: What typing ^D does on Unix (2009)

#40
post #25

^U will clear the buffer - super convenient for retrying botched passwords.

In readline, ^U will only clear from the cursor to the start of the line, leaving anything on the right. ^K is the converse. I'm not sure you are speaking about readline though. Another very useful thing I use daily is Alt-F/B, to move forward/backward in the line one word at a time. Control does the same, one letter at a time. D will delete an element instead.

There's a lot of unexpected gems in the readline defaults. I recommend people try paging through "bind -p" in bash some time to see what's there.

Personal favorites are C-r to search back in history and C-x C-e to edit the current command line in an external editor.

Post reply on HN