Email or username:

Password:

Forgot your password?
233 comments
David E. Smith

@b0rk omg I didn't know rlwrap existed and I am having IDEAS thank you for this post

alexing

@b0rk so like, one issue i have is that my brain isn't perfect at internalizing different input methods for different software. like, i do a lot of code writing in nano and a lot of code writing in notepad++; when i want to search something in nano, i use Ctrl+W, but in notepad++, Ctrl+W closes the current tab... i only make the mistake of using Ctrl+W instead of Ctrl+F in notepad++ maybe 0.5% of the time, but that 0.5% of the time when i end up accidentally closing the file i'm working on is suuuuper infuriating

idk if other people feel the same, but that's one reason why when i do stuff in cli i generally don't use many shortcuts, is i've kind of conditioned myself against those kinds of mistakes lol

@b0rk so like, one issue i have is that my brain isn't perfect at internalizing different input methods for different software. like, i do a lot of code writing in nano and a lot of code writing in notepad++; when i want to search something in nano, i use Ctrl+W, but in notepad++, Ctrl+W closes the current tab... i only make the mistake of using Ctrl+W instead of Ctrl+F in notepad++ maybe 0.5% of the time, but that 0.5% of the time when i end up accidentally closing the file i'm working on is suuuuper infuriating

Colin Campbell

@b0rk One to add to your list, in the emacs bindings you can use Ctrl-P for previous command (i.e.= up arrow)

Julia Evans

@cscaim yea i intentionally left out almost all of the keyboard shortcuts because I don't use them

EaterOfSnacks

@b0rk That was worth it for 'stty -a' alone!

Julia Evans

someone in the replies elsewhere pointed out that Ctrl+J = 10 in the ASCII table = LF ("line feed") = Enter (because J is the 10th letter of the alphabet)

so Ctrl+J is the same as pressing enter

which I don't have any practical use for but is kind of cool

(edit: some corrections in this reply: pgh.social/@ben/11275223526492)

David Monniaux

@b0rk that sort of thing had some meaning when one worked on an Apple // or similar

DELETED

@b0rk This is the kind of thing I'll hear of now, and in 5 years when my enter key switch has gone bad, I'll be more distracted by figuring out what you said vs. just ripping the switch out and plugging a new one in. <3

Chris Gerhard :bt:

@b0rk it's useful if the terminal type is wrong.

Robbie Coleman :verified:

@b0rk
I remember a sysadmin at a company I worked at in 1993 used bat files to program CLIs for users. It would list options where your response would be the file name of that action's bat file, and to "secure" certain options, he would include special ASCII characters in the file name.

Ben Cox

@b0rk This isn't quite right in a few ways. LF is decimal 10, ascii 0x0a. It is 10 because it's the 10th letter of the alphabet, though. But it's not the same as pressing enter except in cooked tty modes, where the terminal driver converts the return key (^M, \r, ASCII 13 / 0x0d) to a newline (^J, LF, 10/0xa) which your program then sees as its input.

Ben Cox

@b0rk NP, sorry if that came off as "reply guy". I once spent a weekend curled up with stty.

Julia Evans

@ben not at all, appreciate it -- edited the original post to link to your comment

Danny Whitt

@b0rk Oh my! This brings memories of ‘\n’ vs. “\r\n” handling back to me, and not in a good way. stackoverflow.com/a/3821814/37

Aurélien Gâteau 🇺🇦

@b0rk Funny that the J character also looks a bit like the ↵ character :)

And the fact that `j` is VIM key to move the cursor down!

Coincidence? I think not!

Ben Cox

@b0rk Old Skool: shift = "subtract 32" / ctrl = "subtract 64" / alt = "subtract (or add!) 128"

Peter Hosey

@b0rk Also Ctrl-H is the backspace character (no matter what your backspace key enters), Ctrl-I is horizontal tab, and Ctrl-L is form feed.

That's also why Ctrl-L is so often the “clear/reset screen” command.

Jamie McCarthy

@boredzo @b0rk For those who didn’t use the paper terminals of the 1970s, “form feed” means the typewriter-style roller, and likely the tractor-feed treads, would engage, to literally roll the paper up a few inches, enough so you could read it, and maybe tear it off for easy transport. The placement of the print apparatus, including the print head or typewriter ball itself, often made it difficult to see clearly what had just been typed

terminals-wiki.org/wiki/index.

@boredzo @b0rk For those who didn’t use the paper terminals of the 1970s, “form feed” means the typewriter-style roller, and likely the tractor-feed treads, would engage, to literally roll the paper up a few inches, enough so you could read it, and maybe tear it off for easy transport. The placement of the print apparatus, including the print head or typewriter ball itself, often made it difficult to see clearly what had just been typed

Ange

@b0rk yes, direct mapping from ctrl codes to characters. Many quirks in this “table” - a lot more than the original “ASCII”.

Luke Harby

@Ange This is like a gorgeous piece of concrete poetry.

D C Ross

@Ange @b0rk
And a lot of those "control character quirks" have just become "how things are done" without anyone ever thinking about how it happened.

You can still use Control-D to exit a shell, Control-G sounds a bell and Control-H is either backspace or delete depending on what kind of computer you're using.

ednl 🇪🇺

@Ange @b0rk In there also: the Escape character Ctrl-[ which we still use in ANSI escape sequences. (Might be a fun realisation: ah yes, that's why the left square bracket is there and they're called Escape sequences.)

jr conlin —〰—

@b0rk

I've always been a bit weirded out about all of that.

For those born in the current millennium: pressing Enter is ^M "Carriage Return" because with out linotype machines, that would make sure you didn't type past the paper. Only you also needed the bar to roll, so you had ^J "Line Feed".

For a while systems would send ^M^J when you pressed the enter key, and some still do (Windows). Others just shortened down to ^J with the ^M implied.

^K, ^L, & ^Y are their own stories too.

zgrep

@b0rk Not the same combination, but I've used ^[ as escape when I couldn't quickly or easily find a way to press the key itself. You may have already come across it, but such control character combinations feel slightly more reasonable to me when looking at a 4-column ASCII table showing all of them: garbagecollected.org/2017/01/3

[Edit: Ooh, this view of the table (from elsewhere in the tree of replies) looks interesting as well: mastodon.social/@Ange/11275225]

@b0rk Not the same combination, but I've used ^[ as escape when I couldn't quickly or easily find a way to press the key itself. You may have already come across it, but such control character combinations feel slightly more reasonable to me when looking at a 4-column ASCII table showing all of them: garbagecollected.org/2017/01/3

hyperpape

@b0rk You use ctrl-j in some contexts in Emacs for what I think is roughly that reason? I think it’s things like regex find/replace where you can’t hit enter or you’ll execute the command prematurely? My memory is a bit fuzzy.

Norman Wilson

@b0rk The important corrolary: control-m is carriage return. Once in a while I encounter a situation in which hitting enter sends LF, but I'm talking to something (usually a tiny-brain embedded device) that expects CR and only CR to end an input line.

Todd Campbell

@b0rk one practical use for it is if your terminal becomes wonky. For example, characters not echoing and enter key not actually working. I've seen this when interrupting an ssh connection before being fully established. You can type 'stty sane' followed by a Ctrl+J and get it back. I do this at least four to five times a year.

Brian Campbell

@b0rk I recall that back in the day, when termcap databases were less complete or had worse defaults, there were some systems that I used to telnet/rsh/ssh into (I forget exactly what era this was) where I couldn't use the backspace key but could use Ctrl-H to backspace. Kind of a fuzzy memory, so I may be getting the exact details incorrect, but these kind random things occasionally do come in handy.

cate

@b0rk it is just how it was designed. control plus keys of ascii lines 4x and 5x gives characters in lines 0 and 1 (block C0).And esc will gives lines 8 and 9 so block C1. But now we uses the “7 bits alias” so esc as control [. Much history but less ideal in modern world. usefulness to know c-j? imho just on binary/hex dumps

Julia Evans

also someone elsewhere left a comment like "I CAN’T BELIEVE IT TOOK HER 15 YEARS TO LEARN BASIC READLINE COMMANDS". those comments are very silly and I'm going to keep writing “it took me 15 years to learn this basic thing" forever because I think it's important for people to know that it's normal to take a long time to learn “basic" things

Feoh

@b0rk This is absolutely positively a true statement.

Peter Hosey

@b0rk Anyone who isn't still learning things 15 or more years into their career—even “basic” things (these are not basic)—is so deep in a rut that they can no longer see out of it.

James Cuff

@b0rk 💯 normal and appreciated, I knew you were going to knock that whole terminal piece out of the park. Well played!

emily dogmom

@b0rk wow! people love to make people feel bad on purpose! thanks for doing what you do to normalize actually needing to learn :)

Sashin

@b0rk I feel like it's unlikely that anyone was trying, struggling for fifteen years to learn them. It's more like they never got around to it. And very likely didn't need that specific piece of knowledge for their day to day.

njvack

@b0rk haha yeah I have been doing this a lot longer than 15 years and this is the first time I have really _thought_ about how terminals work

one thing I don't get is: If ^W isn't handled by readline (or friends), what *is* doing it? How do backspace and word-backspace work?

How... does character entry work at all??

Julia Evans

@njvack honestly I didn't dig into that in the post largely because I don't understand it well either, I think it's the "unix terminal driver", but like what is that?? how does it work? it's a weak point for me and I'm hoping to understand it at some point

Ray Lee

@b0rk working in software requires people to be lifelong learners. Thanks for setting a good example.

dcbaok

@b0rk there are literally millions of basic things no one can learn all of them no matter how many years they have

Aral Balkan

@b0rk I’ve been coding for 40 years. I still learn new things every day. And forget other ones every day. We’re people, not books.

raphael

@b0rk yes, this! so so much this!

like, what is this fictitious world in which every aspect of every tool is learned right away? everybody looks at things from a perspective informed by where they are at that moment and what they want to do. sometimes, that puts the spotlight away from (otherwise) foundational tools. sometimes that puts one in positions where memorising 1–2 command variations without fully understanding the entire tool is good enough(tm).

and everybody has these ‘blind spots’ – i.e. things that were more front and centre for somebody else.

it’s silly to pretend otherwise.

@b0rk yes, this! so so much this!

like, what is this fictitious world in which every aspect of every tool is learned right away? everybody looks at things from a perspective informed by where they are at that moment and what they want to do. sometimes, that puts the spotlight away from (otherwise) foundational tools. sometimes that puts one in positions where memorising 1–2 command variations without fully understanding the entire tool is good enough(tm).

Kevin Boyd

@b0rk right? That sort of commentary serves no purpose. And there's always new stuff to learn.

There's probably even a better way to do my go-to readline use case, one I haven't discovered yet:

```
read -s PASS
export PASS
```

Nick Aubert

@b0rk I've been using variants of the unix command line for 25 years and I'm still stumbling into new things. Nobody knows *everything*.

klutzagon

@b0rk i too was born naked, screaming and confused. and i still ask my partner if 12 past meridiem is noon or midnight.

it always and will never not confuse me.

Paul J Stevens

@b0rk There are lots of 'basic' things I will never learn. Assuming otherwise seems presumptive at best, basically!

Shane Celis

@b0rk I just found out yesterday there are terminal extensions to get key up events in the terminal. I naively thought for the last 20 years those were already there. sw.kovidgoyal.net/kitty/keyboa

anukul

@b0rk there is something particularly juvenile about people assuming there is one particular order or traversal for how people should learn things – that if someone else doesn’t know a particular bit they are BEHIND or BELOW or BASIC.

it’s NORMAL that we all encounter the staggering diversity of technical details at different times and stages and it doesn’t mean something fundamental about your place in the hiearchy.

Gersande La Flèche

@b0rk Comments like that (which I have heard over and over and over all the way back to my baby web dev days making my first website in 2004) only end up ensuring that overly sensitive autodidacts such as myself write off programming as a viable hobby/career forever…

DELETED

@b0rk and not remember all the details from manuals and documentation. But it’s easy to be a smartass on the web writing silly comments

Sky :veryiffied:

@b0rk there is something a little funny to me about how i was (and effectively now am) going to reply to this about how while i am very seasoned with computers and running infrastructure i struggled with git for a long time and so this post resonated with me

but your pinned toot is about your zine “how git works”!!! which i think i will now have to check out

Alvaro :rstats: :python:

@b0rk you're an internet treasure Julia, thanks for doing what u do.

You're like that kid in class that when a teacher explains something complex in a horrible way raises their hand and says "actually I didn't get any of that" and prompts every other student (who don't feel confident enough to admit they didn't understand) to lower their guard and go "yeah no, please explain that again".

Publicly admitting ignorance is so powerful! Nothing that you don't know already of course :D

David Foster

@b0rk Python 3.13 (in beta) has a new custom input editing method inspired by ipython, rather than using readline or libedit docs.python.org/3.13/whatsnew/

Mike

@b0rk Very nice article, (I haven't quite finished yet).
I wanted to point out that ctrl-U is NOT delete the whole line for readline (long ago I had expected it to be that and got surprised).
It is:
unix-line-discard (C-u)
Kill backward from point to the beginning of the line.
The killed text is saved on the kill-ring.

Which you will ONLY discover if you use it after having moved your cursor to the middle (or front) of the line. In which case you'll need to followup w/ ctrl-K

@b0rk Very nice article, (I haven't quite finished yet).
I wanted to point out that ctrl-U is NOT delete the whole line for readline (long ago I had expected it to be that and got surprised).
It is:
unix-line-discard (C-u)
Kill backward from point to the beginning of the line.
The killed text is saved on the kill-ring.

ErwinHoogzaad

@b0rk my favorite is ctrl-g or ASCII character 8 the BEL character. Yes it rings the bell 🛎️ in your terminal.

Justin FItzsimmons

@b0rk great writeup! I learned quite a bit, even though like you I have been using the command line for 15+ years. Had heard of most of this stuff before but didn't really every dig into a deeper understanding, just considered it all "arcane terminal crap, probably sucks for legacy reasons". rlwrap was a really cool thing to learn about though, had never heard of it until reading your post.

peter

@b0rk i always liked how postgres' psql lets you switch into vim mode with \e or \edit and wondered if there was an equivalent in shells

No Gate Key

@b0rk tangentially related: at least some readline sequences (eg Ctrl-A and Ctrl-E for sure) work on OSX not only in the terminal but in Apple-supplied apps which work with text (Notes, TextEdit, Mail, etc) but not /all/ apps; notably Outlook Mail on OSX doesn’t process those sequences. Hugely shocking, I know.

národní prase
@b0rk learned some things today, thanks!
Daniel aka CyReVolt 🐢

@b0rk Yup, and oddly enough, this had been essentially resolved in the 90ies with Plan 9, but people stuck with systems that still keep reminding us of teletypes, core memory, tape drives and all that retro stuff.
Because... legacy, compatibility and fear of change, maybe?

Dave Marquardt

@b0rk As someone in the computer industry since 1984, the terminal was the ONLY way to do things, so you just got used to it or found some other line of work. This idea that working in the terminal is complicated is a different perspective. Thanks.

Sean Hood

@b0rk Huh, TIL! I saw in `stty -a` that `eof = ^D`, is that why Ctrl-D closes a shell/terminates an ssh connection? I've used Ctrl-D probably daily for longer than I know, and never put the two together.

Jeff Grigg

@b0rk

Yea; the dedicated separate "arrow keys" on the keyboard have always been a mess, because there aren't really ASCII codes for them.

Well, there are, but there would be no way to differentiate between arrow keys and Control + H, J, K, & L. And people/vendors wanted separate "arrow" keys. So ... escape codes on input, it is! And that "makes a mess" of command line input that does not interpret the escape codes.

.

They are ANSI escape sequences
(a different standard)

@b0rk

Yea; the dedicated separate "arrow keys" on the keyboard have always been a mess, because there aren't really ASCII codes for them.

Well, there are, but there would be no way to differentiate between arrow keys and Control + H, J, K, & L. And people/vendors wanted separate "arrow" keys. So ... escape codes on input, it is! And that "makes a mess" of command line input that does not interpret the escape codes.

A Lloyd Flanagan

@b0rk Yet another reason everyone should use Emacs! (Seriously though, if you’re a touch typist, the key bindings are extremely well thought out)

Alexander K‮kn‭li

@b0rk if for some reason you don’t have rlwrap, socat can also do this (with READLINE on the “left” and EXEC on the right), even supporting a custom history file.

Curt Bushko

@b0rk you would have so much fun in the Ghostty beta. @mitchellh is always deep in the weeds fighting with terminal oddities.

Matt Cengia

@b0rk I recently started trying Atuin and am in transition from bash to fish as my shell, but found some slightly buggy behaviour using bash with atuin. Has it been relatively smooth for you? I'm still unsure how I feel about it; I like the functionality but occasional like UI bugs and minor delay loading history has added some friction .

psu_13

@b0rk this historical article on multics emacs has a fascinating section about the performance impact of interactive programs on the mainframes of the time. it's interesting to remember that terminals were computing. entities in their own right, with local state and whatnot.... which is not a picture you see much anymore.

multicians.org/mepap.html#secv

Garrett Wollman

@b0rk The Korn shell supported command-line editing and a weird flavor of history editing (check out the `fc` command), and the POSIX.2 shell was based on ksh, so support for both `emacs` and `vi` modes in interactive shells is pretty much universal except in antique or deliberately minimal shells. Technically it's optional but the Standard says what the supported keybindings are in both modes.

Mehrad :kde: :emacs: :rstats:

@b0rk
Thanks for the article. I didn't know about rlwrap. Should be super handy tool.

Btw, most of the readline keybindings are similar in Emacs, but as a tip, if you want to know what a keybinding does in Emacs, open Emacs vanilla (`emacs -Q`) then press Ctrl-h and then k. This will ask you to press a keybinding and it will give you its definition.

Ian Sudbery

@b0rk fascinating! I was wondering if readline copied emacs or vice versa, and now I know!

I wonder if long time emacs users (as opposed to vi users) find the terminal more intuitive?

Sami Samhuri

@b0rk You’re a hero for writing this stuff up and your style is great. Thanks for being awesome!

the esoteric programmer

@b0rk I didn't ever hear about ctrl+u, ctrl+w, ctrl+r, etc, so yes, that stuff is definitely hard. I wonder though, why are arrow keys printing those characters when pressed in a non-interactive input prompt? hmm, I think I gotta read some C to find that out, maybe. This post is very interesting, bookmarked it

Addison

@b0rk@social.jvns.ca I know you omitted the ones you don't personally use, but I find Ctrl-K quite useful as well for clearing out everything after the cursor. This is really useful when you are using the same commands for different things (Ctrl-A, navigate to the end of the bit you want to keep, Ctrl-K).

I teach this guy along with the others you mentioned in your post to people new to shells because these really do help with text task automation :) Nice to have a (readable and friendly) source for these

Lindsey Kuper

@b0rk I probably wouldn't know the readline commands if I weren't an Emacs user. And even as an Emacs user, I have about 8 readline commands in muscle memory and that's good enough.

James Truitt (he/him)

@b0rk Dang, I learned so many useful commands from your post and the links it provides. Thank you so much!

akahn

@b0rk I also came to the Emacs strokes late, as a Vim user. one great thing about learning them is that they work in a lot of macOS UIs too. In particular ctrl-p/ctrl-n

Simon Racz

@b0rk thanks for the post. I learned new things from it. I love your approach to learning.

I did a similar investigation some time ago. In the end I made a game in the terminal to make it more interesting. :)

youtu.be/WvSOSyi5lWY

noone

@b0rk CTL-[ is still how I type ESCAPE, due to too many years of odd keyboard layouts.

Go Up