What typing ^D does on Unix (2009)
utcc.utoronto.ca
utcc.utoronto.ca
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).
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.But indeed, it's in raw mode so the kernel doesn't do anything special and just emits the 0x04 byte down the descriptor.
http://stackoverflow.com/questions/15666923/sys-stdin-does-n...
http://www.linusakesson.net/programming/tty/
...and the extensive previous HN discussion on it:
https://news.ycombinator.com/item?id=10631513
https://news.ycombinator.com/item?id=10064657
https://news.ycombinator.com/item?id=8094186
https://news.ycombinator.com/item?id=4544318
(For example, if I type some stuff and then ^U to kill the password buffer at an SSH password prompt, typing ^Y after that seems to put the whole process in the background. Not sure what that's intended to do, but subsequent ^Y presses don't retrieve the password into the shell prompt...)
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).
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.
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.
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.
if [[ $- == *i* ]]
then
bind '"\e[A": history-search-backward'
bind '"\e[B": history-search-forward'
fi
(fix: grammar)What's the point to type a half-command and then replace input line with one from history if I press up? That somewhat resembles ugly cmd.exe, which every windows user imagines when someone says 'cli'.
I use "yank-last-arg" most often, which is M-. by default.
$ mkdir abcd
$ cd <M-.>
On Zsh, I have M-, bound to "copy-earlier-word", which makes M-. M-, M-, cycle through the arguments to the previous command.In reading the manpage for Bash, which doesn't have this function, I've just found "history-search-backward", which searches through history to find commands based on what you've already typed. That will come in useful!
$ bind '"\er":history-search-backward'
$ bind <M-r>
(Note that M-r is bound to "revert-line" by default, but I doubt I'll use that.)These functions are all listed, with explanations, in the Bash and Zsh manpages.
Edit: As I see from another comment, a binding for "history-search-backward" to the Page Up key is in /etc/inputrc on Debian and derivatives.
This is the shortcut to first learn when starting living in the command line.
Actually, just go read http://ss64.com/bash/syntax-keyboard.html or something, once per day, integrate a new one each time, and you will improve your productivity on the command line (as well as comfort).
Nice link - reminds me to try to use the history stuff like ! and ^ more.
Then you give them a puzzled look once you successfully log in as if nothing out of the ordinary just happened and say something like "What, don't you have a sufficiently complex password?".
Edit: It was just a joke :(
<anecdote> I actually had a sufficiently complex password, but this one time I was in a massive hurry to demo something to my teammates, I made a mistake somewhere near the end of it, quickly typed ^U, fed it all over again, made another mistake near the end, another quick ^U, and third time was the charm.
They didn't notice that I reset the password field twice, to them it was just a mega-super-duper-long password (the actual password is 20+ characters), and one of them burst out saying, "Woah! He just wrote a short story!" </anecdote>
I have the Caps key mapped to control, so ^M is 2 small finger movements as opposed to reaching for the return key which means either moving my (weak in my case) right wrist or moving my whole right forearm. It's a small movement to the return key but I find eliminating it really helps to reduce strain related pain when typing.
I also use ^H for backspace and ^I for tab for similar reasons. This also keeps my fingers on the home row.
Some vendors had bugs in which when +++ appeared as part of the incoming data it would also trigger the firmware escape.
And of course programmable terminals had hilarious exploits where you'd get someone to run your program, it would program the terminal to emit a macro when you hit enter, the macro would include +++ATZ, etc., etc.
My favorite modem story was when I worked for a company that shipped auto parts warehouse management systems. They would have several SCO unix boxes with serial port concentrator cards and port concentrators on those concentrators, such that you'd have 256 modems on a single box and RS-232 cables everywhere. Frequently the operators at the auto parts warehouses couldn't be bothered to do cable management, so at one facility, the entire floor of the server closet was carpeted literally 2 feet thick with a random mess of RS-232 cables, each one leading to a modem. When standing on the cables killed a modem or two, they would just string a new wire rather than try to fish out the old one. Kind of like Google's "let it sit in the rack" policy for failed servers, but writ extremely small and pathologically badly.
So do they do scheduled collections of failed units? Or just let them sit there indefinitely?
For most of the SMB clients I have, I don't build new servers any longer. I can buy rackmount servers pulled out of a data center that are a few years old at about 1/3 the price. I just put new disks in them and a new OS.
Many years ago, modem maker Hayes Microcomputer Products held a patent dealing with that issue. The clever bit was in looking for
<pause> +++ <pause>
to effect the escape.Hayes tried to collect royalties, but this caused quite a kerfuffle. Cheap modem makers didn't bother looking for pauses. "Hilarity" ensued. Other solutions were found.
https://en.wikipedia.org/wiki/Time_Independent_Escape_Sequen...
Kidding of course, but once upon a time many 56k6 modem contained a bug that, upon receiving this in plain text, would cause an actual modem hangup. You could kill hundreds of IRC connections with that one.
In the 'icanon' mode, the terminal driver implements a rustic line editor, so you can do things like Backspace to delete previous characters and so on. Pressing Enter during this mode returns the edited buffer line to the program.
Where Ctrl+D, or EOF, comes in is when you want to return a line to the program _without_ pressing Enter. This is where the terminal driver returns the buffer to the read() function for the program immediately. Doing it again with no additional input shows that you were done line-editing, so it simply returns nothing, signaling the program that you're done editing or providing input - the intended purpose of End Of File, the character sent by Ctrl+D. (If you were reading a file and you received nothing on a read... you would be at the end of a file, because why else would the file have nothing else to read?)
But this 'icanon' mode won't be active in your actual terminal shell, because shells have their own line editing implementation, so they turn 'icanon' off by default. You can, of course, turn on or off in the terminal with "stty". Use "stty -a" to see all the other current settings. The terminal application, by the way, sets the EOF to the same value as the terminal driver's by default, in order to prevent confusion.
Instant reply Without any latency: "It originally was meant to terminate the Tape drive"
You can also type "<cr>~?" for a list of other commands supported by the local ssh client. Among other things, "<cr>~C" opens a command line interpreter on the client side of the ssh client, allowing you to add and remove TCP port forwarding without restarting the connection.
You log in, type "rz<enter>", and then use escape sequence to upload a file. (similar for downloading)
The patch was rejected. Shame. It's very useful when hopping 6 steps to upload a file.[1]
I can't find the patch now, but I'm considering rewriting it as a an `expect` script. My `expect` scripts tend to have trouble with SIGWINCH propagation though, so not optimal. Also you have to remember to wrap with the `expect` script at (and preferably only at) the one "jump" you want to send from/to with the final destination.
[1] No, nothing illegal. Just that some networks mandate SSH jumpgates, and sometimes multi-level.
\n~~. will escape the 2nd box you've SSH'd to, not the one it was originated from.
Useful for escaping a screen'd SSH session that you might access through a jumphost.
Specifically, the escape sequence is "\n~", with various options (visible by typing "\n~?"), and if the option is unknown it passes the "\n~{x}" as-is.
The biggest false positive you'll see is "\n~v", when executing bins out of the home dir of a user starting with the letter 'v'.
For example, type ~^Z to put a session in the background.
Similarly, type ~~ to send an escape sequence in an inner session, etc...
There's a program called SSH to get to another CPU.
Tilde is the escape, it's doubled to send it through,
And "quit" is tilde-.
I think you know how the rest goes...If you have an ACM subscription, the sheet music was published in Communications of the ACM (Volume 27, Issue 4; April 1984): http://dl.acm.org/citation.cfm?id=1035691
It's so beautiful. I think I'm going to cry :)
For reference it means Ctrl+D, unless you you have a strange keyboard from Sun or something.
On top of that, the shortened 'ctrl' is really a terrible abbreviation. It's not obvious that it stands for 'control' and I would guess that most non-techy people would have no idea that it means this word. Plus, it's near to another key with multiple letters ('alt'). The overall effect is that 'ctrl' appears to just be a jumble of letters with some esoteric meaning. A really odd design decision. Why not just put 'control' on the key and be done with it?
Not sure I've ever seen a Mac keyboard that said "control", but maybe that's because I've mostly seen Finnish keycaps.
Perhaps the standard is something to do with the country (mine is a UK layout).
Anyways, I had the same issue when I first started using Linux. It probably took me over a year to realize the caret stood for ctrl, and that's only because I accidentally typed it in something that printed the codes literally.
Also note that on some keyboards it has the U+2638 character engraved.
Right, and the classic book The Unix Programming Environment (by Brian Kernighan and Rob Pike) uses ctl-d.
So many games don't even allow you to open the console, because they assume that your key next to 1 is ~, and so don't work for § (next to 1) or altgr+¨ (the layout's ~). Or switch between looking at characters or scancodes depending on the context, and thus work in some cases but not all.
It's never used anymore, I suppose, except for the old school people who still have enough muscular memory built up to write it that way. I know I do; I learned it from some computer magazine in the 80's and have a hard time letting go.
I was born after the 80s, and I use that shorthand (although I suppose this probably says more about me than it does about the shorthand itself). I didn't even understand the original comment until I read through the whole thing because I mentally read it as "Ctrl+D"
And since we're on this topic: if I write a for loop in bash that runs a slow command 1000 times (ImageMagick comes to mind), and I realise something has gone wrong, is there an easy way of breaking the outer loop?
How? Do you have a keyboard where | isn't Shift+\?
https://en.m.wikipedia.org/wiki/File:Keyboard_Layout_Norwegi...
If it's part of a script, your script probably wants to trap SIGINT.
^Z
fg
^C
the ^Z kills the loop, the fg and ^C cleans up the currently running one.
https://en.wikipedia.org/wiki/Control-%5C
https://en.wikipedia.org/wiki/Core_dump
https://en.wikipedia.org/wiki/Control-C
I remember doing:
sdb a.out . core
or something like that, in my C-on-Unix programming days earlier :)
sdb was a debugger.
UNIX one-liner to kill a hanging Firefox process:
http://jugad2.blogspot.in/2008/09/unix-one-liner-to-kill-han...
Some interesting comments on that post too, which go into slightly deeper details.
Here's the rest in one place:
eof VEOF EOF character
eol VEOL EOL character
eol2 VEOL2 EOL2 character
erase VERASE ERASE character
erase2 VERASE2 ERASE2 character
werase VWERASE WERASE character
intr VINTR INTR character
kill VKILL KILL character
quit VQUIT QUIT character
susp VSUSP SUSP character
start VSTART START character
stop VSTOP STOP character
dsusp VDSUSP DSUSP character
lnext VLNEXT LNEXT character
reprint VREPRINT REPRINT character
status VSTATUS STATUS character
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
stop = ^S; susp = ^Z; time = 0; werase = ^W;sed nq file
where n is some positive integer, to print the first n lines of the file.
Also, body (the complement of head and tail :)
# body
sed -n $1,$2p $3
$ stty -a | grep -F '^D'
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
$ 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 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
It doesn't clear the screen; it just issues a newline and reprints the characters buffered so far. You can use stty to assign ^L to "rprnt".On Linux, some programs (e.g. dd) actually do the same in SIGUSR1. I don't think it's possible to bind a key to sending USR1 so if you start a long dd you have to run the kill1 -USR from another shell. Or an awkward ^Z, then`kill -USR1 $(jobs -p)` then `fg`.
In the C standard library, you just clearerr(stdin) and keep reading.
If a program takes two files as input and obeys the - convention for specifying stdin (or has some other way of opening the tty more than once), you can do:
$ program - -
then give it two inputs, each followed by [Ctrl-D][Enter]. For instance "cat - -".This sort of thing subtly breaks with some utilities. Try coaxing GNU diff to compare two pieces of tty input, haha.
$ program <(cat) <(cat)
The program itself isn't involved in opening the TTY / reading from it, etc, that is all handled by your shell before fork/execing program. program doesn't know that any of these shenanigans have happened.It probably uses more memory (the shell has to have both stdin's in memory before it can exec the program), but overall I have mostly abandoned trying to use '-' as an input because of the way some tools, perhaps less-steeped in unix-y traditions, don't honor it correctly.