Honestly I had no idea what ctrl+d even did, I just knew it was a convenient way for me to close all the REPL programs I use. The fact that it is similar to pressing enter really surprised me, so I wanted to share this knowledge with you :)
Honestly I had no idea what ctrl+d even did, I just knew it was a convenient way for me to close all the REPL programs I use. The fact that it is similar to pressing enter really surprised me, so I wanted to share this knowledge with you :)
Ctl-D is the End-of-File character. Programs interpret it as “that’s it, the input you were reading has finished”, and react accordingly.
$ cat You sound very nice :) You sound very nice :) Bye<ctl-d>Bye Oh wait, and cool too Oh wait, and cool too <ctl-d> $
The Ctl-D didn’t end the file when i typed “Bye” :( it only worked when I pressed Ctl-D on its own line. So how does cat know that it should ignore the EOF character if there is some text that comes before it?
What Ctl-D does is flush the input to the program, and the program sees how big that input is. If the length of the input is 0 that is interpreted as EOF. So Ctl-D is like Enter because they both flush the input, but Ctl-D is unlike Enter because it does not append a newline before flushing, and as a consequence you can send empty input (aka an EOF “character”) with Ctl-D.
When running cat this way, you are in “cooked mode”. A ctrl-d does nothing on a non-empty line.
The shell usually runs in non-cokked, or raw, mode as well as nonblocking mode. Where it sees (nearly) every key you press as you press them. Which is why it " sees" the ctrl-d even when you are not on an empty line.
You can learn more here:
Interesting, I have not heard of these terms before. Thanks for sharing!
I think this adds the bit of nuance that was bugging me: using something like ncurses or vim, presumably when you press a key like ctrl-z or ctrl-d it actually sends the character to the app. It would feel a bit silly if the terminal intercepted the ctrl-d, flushed some buffer, and the program had to reverse engineer whether you pressed ctrl-d or enter or something.
For raw mode, I assume the app asks the tty to please forward some characters to the app. Otherwise, in the default cooked mode, the tty intercepts those control characters to call certain functions. I suppose some REPLs may choose to emulate a cooked mode on top of raw mode, and so they have to handle the \x04 in the same way a tty would to keep it functioning like the user expects. I believe
readline
does something like this, which is why you had to usebash --noediting
for ctrl-d to run the command. Good food for thought :)I also have to say, naming it “cooked mode” is extremely funny as gen z. I love that
ctrl-d actually is flushing the buffer regardless of if the line is empty or not.
See my other comment for how you can observe it.
This!
It’s merely a buffer flush, in case it’s empty, the program handling the input can choose how to interpret,
cat
decides to do it as an EOF.Reason why it also works as exit.