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

  • $ cat
    You sound very nice :)
    You sound very nice :)
    ByeBye
    
    Oh wait, and cool too
    Oh wait, and cool too
    
    $ 
    

    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 use bash --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