every so often I get confused because I'm writing a zine about the terminal and didn't I already write 4 zines about the terminal???

but I've never written about what the UI “rules” you need to know to use the terminal interactively are, only:

- notes on core Unix concepts — file descriptors, signals, etc (Bite Size Linux)
- shell scripting (Bite Size Bash)
- cheat sheets for sed/grep/xargs/etc (Bite Size Command Line)
- cheat sheets for command line networking tools (Bite Size Networking)

I haven't totally sold myself yet on this "what are the secret rules of the terminal?” framing but it feels like a reasonable way to talk about how, even though “the terminal” is a lot of separate things working together, it "feels" like a cohesive environment that has a lot of rules that you can generally expect to be true.

Some of those rules are Unchangeable Facts and some of them are just Vague Social Rules but understanding the vague social rules is just as important as knowing The Facts.

an example of a "social rule" in the terminal is that if you have a noninteractive program, you can generally expect that `Ctrl-C` will stop it, programs can do whatever they want but it would just be kind of rude for a noninteractive program to not respect `Ctrl-C`

(there are different and more complicated social expectations around how to quit interactive programs)

another example of a "social rule" is that at an interactive prompt you should expect `Ctrl-W` to delete the last word, this is weird because depending on the _kind_ of program, the exact mechanism for how `Ctrl-W` will delete the last word might change, but I think it would be generally considered rude if a program with an interactive prompt treated `Ctrl-W` in a different way

(text editors are an exception though and generally are allowed to handle text editing however they please)

another social rule is that if a program is writing its stdout to a file or pipe, it's expected to turn off colour codes so that users don't end up looking at output like this:

ESC[1;33massets.jsESC[0m

(as far as I know there is almost nothing enforcing this behaviour except that users will be unhappy if you don't do it)

another funny example of a "social rule" in the terminal is that it's not actually considered THAT rude for a program to not support arrow keys, like if the program only takes very limited interactive input (like just `y`/`n` or entering a number), then it's normal for the arrow keys to not work. Git is an example of this.

i forgot to put “please don’t explain how terminal keybindings work to me” on this thread and i’m regretting it, anyway, please don’t, i wrote 4000 words about it if anyone wants a deep dive
https://jvns.ca/blog/2024/10/31/ascii-control-characters/

https://jvns.ca/blog/2024/07/08/readline/

ASCII control characters in my terminal

ASCII control characters in my terminal

Julia Evans
@b0rk Now I feel slightly guilty for explaining how `dup` works on that `stderr` redirection question… Sorry! (But hopefully I at least also validated the “try the wrong way, then the other one” as a viable alternate methodology 😂)
@zellyn nah i always appreciate when people share their relationship to the fact (like “knowing this does not help me”), i know about dup but i don’t know how you relate to it :)
@b0rk oh yeah, I’ve been disentangling so many of these in my head recently! Are you interested in more examples?
@b0rk you might enjoy playing around with misbehaving.site, which has a bunch of URLs you can curl and which, depending on the implementation, can do all sorts of things (like minimize your terminal)
@b0rk speaking of y/n prompts -- another pattern (or rule): if one of the options is stated in upper case, it should work as a default when pressing only the enter key
@jn
It took me a while to realize this implied a default instead of the necessity to type the letter in uppercase.
@b0rk
@b0rk I don't know if it is a social rule, but rather common behavior enforced by the TTY driver that the terminal program uses. Or, rather, that the kernel runs whenever somebody reads from a terminal.
@rsalz @b0rk nope, the tty doesn't do anything with such escape sequences. The following stackexchange explains it quite well: https://unix.stackexchange.com/a/103764
Is there any reason why I get ^[[A when I press up arrow at the console login screen?

Whenever I'm at the console login, I press up arrow intentionally to see the previously typed commands. But I see this ^[[A. But when I press Ctrl Alt Print Screen Scroll Lock Pause Break Page Up ...

Unix & Linux Stack Exchange
@sam @b0rk it does some of the things like ctrlC ctrlW delete etc
@rsalz @sam can you leave me out of this conversation thanks
@rsalz Ok yeah I get it. And the kernel eats ctrl+alt+delete/shift+alt+FX/...
@b0rk I thought of arguments having the short (ls -l) or long (ls --help) forms as a rule. But then there are the single-dash long forms (find . -type d), or the insane things like iproute(8), with -a/-all but also -br/-brief 😩
@b0rk in addition to that, when the arguments have values the rule I think should be -lvalue and --long=value... But again, many exceptions to this rule

@b0rk

I think that each time I write a script, I have to decide all over again whether to accept a single keystroke or to accept a whole line of input.

AFAIK, there's no consensus on that.

@b0rk Love coming across threads of yours like this - they always make me stop and think. Like every time I hit ctrl-c and a command just quits I'm honestly a little surprised.
@b0rk that reminds ne that filtering these out shoiluld be an obvious capability of my terminedia project . (I still have no parser dor these ANSI codes)
@b0rk as an aside: my life was forever changed when I learned of less -R (raw), which lets you see saved output like that with colors. It doesn't help if you'd hoped to parse it ofc, but if you're reading it's nice not to have to try filtering those codes out with your eyeballs. 😃
@jericevans @b0rk I actually *like* to have coloured output also in `less`. So, I always have to find out what the option for “always with colour” is to give it to `less -R`.
@b0rk I really wish we could have structured data across pipes just so we could get highlighting back at the end of pipe-based tool chaining. Lumin is nice enough, but thin gruel in comparison.
@mhoye @b0rk this is one of the few things I really like about Powershell.
@petrillic @mhoye @b0rk nushell also does structured data, and is cross-platform
@itamarst @mhoye @b0rk oooo will check it out. I hate the general syntax of Powershell but the structured data aspect is a huge win.

@petrillic @itamarst @b0rk

I’m convinced that if powershell had been born anywhere but Microsoft it would have replaced bash entirely by now. Even structured data is thin gruel compared to pipelines passing structures objects.

@itamarst @petrillic @mhoye @b0rk

https://www.nushell.sh to save someone else some clicks. I’m definitely going to take a look at this.

I’m not sure if I found the right lumin? https://lumin.readthedocs.io/en/stable/

Nushell

A new type of shell.

@b0rk And it can be annoying when some apps handle this differently. For example, I think most utilities will check both isatty() and TERM != dumb to enable colouring by default. However, it seems like PowerShell only checks the latter, so it'll emit ANSI codes even when stdout is not a TTY.

@b0rk it's not a social role, it's necessary to not break pipes. For example

echo this is the way | grep the | grep 'the way'

If the middle grep outputs ansi codes to colorize "the" to make it stand out, the last grep will not match and therefore output nothing.

@b0rk The old social rule I observe is that you never output color or other terminal escapes in straight output (not bidirectional terminal ui) regardless of whether output us a tty or not unless explicitly asked to, and I am angry every time some program violates that and I have to stop what I'm doing and spend 30 yak-shaving minutes researching how to get it to stop.
@b0rk Every time I notice that a program correctly follows the "social rule" of un-colorising it's stdout hen it's writing to a pipe, I briefly wonder: how? How does it know where it's stdout is going? Some day I'll learn how to do that in my programs.
@dan I believe the general mechanism is isatty(3). I sometimes wish there were a way (an easy way?) to spoof this, because sometimes I want to redirect a program's tty-flavored output but cannot find a `--color always` equivalent flag.

@The0x539 Interesting. Don't know anything about it (yet!).

Can you spoof if by eg just piping to `cat`, or to `tee /dev/null` or something?

@The0x539 @dan you can use “unbuffer program” to make its stdout a tty even if you redirect the output

@dan In unix and c it's the isatty() function. Usually you'd call that on stdout.

https://man.archlinux.org/man/isatty.3.en

Most other platforms and languages probably have something similar. For instance, when I duckduckgo "python isatty", "rust isatty", "golang isatty", "java isatty", or "js isatty", I find an example within the first couple hits.

Hope that helps!

isatty(3) — Arch manual pages

@dan using istty on stdout file descriptor (1)
@b0rk TIL that Ctrl-W does that
@b0rk re ctrl+w: FWIW this is a *emacs key binding*. This is a similar standard to j/k/ctrl+d/ctrl+u for scrolling which is vi-style (the emacs alternatives which are also used some times are ctrl+n/ctrl+p/ctrl+v/alt+v).

@b0rk readline and its many assorted clones use Emacs bindings by default, as does Bash (perhaps Bash uses readline?). e.g. Ctrl-a goes to the beginning of the line, Ctrl-e goes to the end, Meta-b goes to the beginning of the current word, etc.

Ctrl-w is a weird one because in Emacs this means "kill" (analogous to "cut") and usually you have to have some text selected for it to do anything useful. In some implementations, Ctrl-y (Emacs' "yank") will paste back what you killed.

@j3rn i forgot to put “please don’t explain how terminal keybindings work to me” on this thread and i’m really regretting it
@b0rk How many Emacs bindings a program implements varies widely. e.g. Bash and psql both have good support, SQL Server's sqlcmd has rather bad support.
@b0rk that one may be more of a Unix convention. In Windows, I expect ctrl-backspace to delete the previous word, and when something wants me to use ctrl-w, I get annoyed because I never remember it. Cross platform is hard, but I hadn't realised how much of that could be due to differing social norms.
@b0rk what, in your experience, is the convention for Ctrl-D? I don’t know what programs have taught me this, but if Ctrl-C doesn’t quit an app Ctrl-D is the next thing I try.
@sfaxon there deal is that if a program has an interactive prompt (like python3) you can quit it with Ctrl D
@b0rk Is it still a social rule that terminals respect control-S/control-Q flow control? I helped a lot of people “unfreeze” their terminals back in the day after they fat fingered their way to sending a control-S!
@dwenius i think so? personally I've been using fish for the last ~10 years which disables Ctrl+S completely by default so I don't have much of a relationship with it personally
@b0rk I’ll check when I get back to my laptop, I’m super curious now :) I know *I* haven’t unintentionally frozen my screen lately, but maybe that’s just because my typing accuracy finally improved to the point I don’t hit that combo?

@dwenius @b0rk It's still a standard Linux pty behavior, and it doesn't look like default shell or terminal configurations disable the stop and start characters, either in eg gnome-terminal or in a console text login. I use it periodically to freeze program output so I can scan it before too much scrolls by.

(Did I just boot a VM and then fire up a KVM over IP interface just to check for sure? Yep, yep I did. I felt I couldn't trust my own desktop environment or ssh from it.)

@b0rk Aside: have you shared your fish config and functions anywhere? I’d be interested to see how you set things up, as I keep bouncing off of fish despite it seeming like just my kind of thing…
@dwenius I basically don't configure fish at all (other than aliases, PATH, and some environment variables) but I wrote a blog post about why I like it! https://jvns.ca/blog/2024/09/12/reasons-i--still--love-fish/
Reasons I still love the fish shell

Reasons I still love the fish shell

Julia Evans
@b0rk Brilliant, thank you!

@b0rk ah! yeah! we think you're absolutely right to call this a social rule

along with the whole success is silent, failure is noisy thing

and the use of ^D to exit from prompt-like interactions

and probably other stuff we're forgetting

@b0rk if we haven't already pointed you at man intro as somebody's long-ago proposed list of topics beginners should know, please consider this our recommendation to give that a look, too
@b0rk I think the fact that this is a social rule (and not one of the Laws of Terminal Physics) is probably a really good thing to include in the framing. It explains what you should debug and who you should blame if things aren't doing what you expect.