[HN Gopher] A terminal case of Linux
       ___________________________________________________________________
        
       A terminal case of Linux
        
       Author : luu
       Score  : 113 points
       Date   : 2023-05-29 08:51 UTC (14 hours ago)
        
 (HTM) web link (fasterthanli.me)
 (TXT) w3m dump (fasterthanli.me)
        
       | JdeBP wrote:
       | A lengthy discussion alluding to the pitfalls of mixing fork()
       | arbitrarily with libraries and threads, discussing terminal sizes
       | in the line discipline and on the terminal itself (although
       | missing that these aren't necessarily the same), showing how
       | library functions are underpinned by system calls, and basically
       | covering the ground that led to the invention of Daniel J.
       | Bernstein's pty tool in 1990 and others.
       | 
       | * https://jdebp.uk/Softwares/djbwares/bernstein-ptyget.html
       | 
       | There's even scope for observation that, like the number of
       | processes that get spawned and instructions that get executed to
       | increment an integer shell variable by 1 (in the traditional way
       | using expr), it's taking four extra forked processes just to
       | write a coloured shell prompt.
       | 
       | Hacker News comments don't get beyond the useless use of cat
       | aside in the third paragraph. (-:
        
         | mananaysiempre wrote:
         | Huh, go figure. I've always used `unbuffer` from the expect
         | package to make things think they are connected to a tty and
         | was annoyed at the bulkiness of that solution (IIRC it's an
         | invocation of `expect` with a passthrough script).
        
       | VWWHFSfQ wrote:
       | I enjoyed the _meat_ of the article, but really disliked the
       | stream-of-thought narrative of the post. But I know it's this
       | author's style. So that's fine.
       | 
       | Anyway. Is there something better than just screen-shotting your
       | terminal window and making PNGs or GIFs for stuff like this?
        
         | fasterthanlime wrote:
         | > Is there something better than just screen-shotting your
         | terminal window and making PNGs or GIFs for stuff like this?
         | 
         | There is and it's been on my TODO list forever. In fact, the
         | article you just read (congrats on getting through my narrative
         | devices) was written /while tackling that/.
         | 
         | https://asciinema.org does it for "moving pictures", it
         | shouldn't be too hard to do it for stills.
        
         | the-printer wrote:
         | These sort of articles are popular for a reason, maybe it
         | reflects a pedagogical trend both ways (preferences in teaching
         | and how one likes to be taught). Personally I gravitate in the
         | opposite direction.
         | 
         | I've come to appreciate "dry", technical guides void of overt
         | personality. I'm not a fan of "Why_'s Poignant Guide to Ruby"
         | in the least, but there is a visceral element in its
         | whimsicalness (and other why_ materially) that similar efforts
         | don't compare to (I count the listed guide here among this).
         | For me, why_'s work is an outlier in this "literary tech
         | writing" genre. If I ever intended to learn the language, I
         | would contemplate scrubbing out the comic strips if I couldn't
         | find a better alternative guide.
        
         | Agingcoder wrote:
         | I couldn't finish it, it felt like noise to me. It was also
         | frustrating because there was little content and a lot of
         | words/pictures (even the prompt was distracting).
         | 
         | I guess I'm getting too old for this - I'm leaving this to the
         | younger crowd !
        
         | JdeBP wrote:
         | That's an interesting thought. _Obviously_ one can present this
         | stuff as just in-line text instead of using images, with
         | appropriate styles for monospacing and colours (although that
         | does then highlight that these fancy prompts often make
         | unwarranted assumptions about what 's in the Unicode Private
         | Use Area). There are many WWW pages out there doing exactly
         | that. But I for one have not heard of a tool that can
         | screenshot a text terminal emulator's buffer straight into
         | HTML.
        
         | quesera wrote:
         | > _I enjoyed the _meat_ of the article, but really disliked the
         | stream-of-thought narrative of the post. But I know it 's this
         | author's style. So that's fine._
         | 
         | This is why it was such a struggle for me to get through
         | _Godel, Escher, Bach_ as well. If I 'm engaged on the topic, I
         | want the author to get straight to the point, not to try to
         | anticipate my questions or lead me with someone else's potted
         | questions.
         | 
         | > _Anyway. Is there something better than just screen-shotting
         | your terminal window and making PNGs or GIFs for stuff like
         | this?_
         | 
         | I've done it manually in HTML/CSS for documentation, to
         | preserve copy-pasteability. It's straightforward: body bgcolor,
         | and font-family (something fixed width), then a bunch of spans
         | with colors for syntax highlighting.
         | 
         | Would love to find something automatic though! E.g.:
         | command | ttyansi2htmlcss | pbcopy
        
           | JdeBP wrote:
           | Well there's http://www.andre-
           | simon.de/doku/ansifilter/en/ansifilter.php for the latter.
           | But it doesn't do direct screenshots. So one would have to
           | find something else that would take the terminal emulator's
           | display grid and, ironically, turn it _back_ into a sequence
           | of characters, escapes, and control sequences.
        
         | ilyt wrote:
         | Yeah I pretty much skipped over it looking for some tidbit I
         | don't know as terminal workings are pretty well known to me
         | already but _ugh_ it 's painful to read for that type of
         | article.
         | 
         | I think that style could work well when you're doing say a
         | post-mortem of some failure, where you want to show the whole
         | train of thought that lead to it or to finding a fix, but for
         | this kind it just doesn't work very well
        
         | endigma wrote:
         | Moving pictures: https://asciinema.org/
         | https://github.com/charmbracelet/vhs
         | 
         | Still image: https://github.com/nbedos/termtosvg (dead, unknown
         | if usable?)
        
           | fbdab103 wrote:
           | Any notable differences between asciicnema and vhs?
        
       | pxc wrote:
       | Besides per-program flags like `--color=always`, you can use the
       | `unbuffer` command1 from the expect package2 to make a program
       | that you're piping act like it's being run interactively (pretty
       | printed, colorized, etc.). Unbuffer is a command that takes a
       | command in its command line, so you run it like
       | unbuffer rg TODO src/
       | 
       | or                 find . -iname '*.md' -exec unbuffer ls {} \; |
       | less -R
       | 
       | or                 unbuffer cowsay --rainbow 'Hello from a very
       | colorful cow!' | sudo wall --nobanner
       | 
       | and so on.
       | 
       | If you make an alias or an abbreviation for your shell, it ends
       | up being more convenient than figuring out all the flags for
       | making piped output look like interactive input for each
       | individual program you might want to use that way. :)
       | 
       | --
       | 
       | 1: https://manpages.org/unbuffer
       | 
       | 2: https://core.tcl-lang.org/expect/index
        
       | drewg123 wrote:
       | I hate colorized output with a passion and disable it in my
       | personal shell. You never know what the background color of a
       | terminal might be, and there is a good chance at least one color
       | will disappear entirely into the terminal background.
       | 
       | Nothing grinds my gears like the _DARK BLUE_ on _BLACK_ colors in
       | the UEFI shell.
        
         | charcircuit wrote:
         | >You never know what the background color of a terminal might
         | be
         | 
         | You can set the background color to. So if you set the
         | background to dark grey you can assume the background is dark
         | grey. Assuming the terminal supports color that is.
        
         | cyclotron3k wrote:
         | Each to their own of course, but I can't imagine _not_ using
         | colours. It would be like using a code editor with syntax
         | highlighting turned off. Madness!
        
           | chungy wrote:
           | Some of us started with editors that didn't have syntax
           | highlighting at all.
        
             | dredmorbius wrote:
             | Everything reminds me of my ex.
        
         | dredmorbius wrote:
         | Even on revered terminals such as xterm or rxvt (and variants)
         | it's often possible to modify the displayed characteristics of
         | ANSI colour sequences, see:
         | 
         | <https://invisible-
         | island.net/xterm/xterm.faq.html#color_by_n...>
         | 
         | Researching this comment I found it's also possible to toggle
         | urxvt colour themes _on the fly_ , via Stack Exchange:
         | <https://unix.stackexchange.com/questions/296257/different-
         | co...>
         | 
         | I'm not sure that this is also possible on, say, the Linux
         | console itself, though I suspect it may be.
         | 
         | I too had a first impression over a quarter-century ago the
         | first time I saw a colourised 'ls' output on my first freshly-
         | installed Linux system that they were garish, and have often
         | griped about dark-blue-on-black (which is how I'd discovered
         | the palette configurations referenced above). But I quickly
         | found the feature useful and helpful and miss it when on a true
         | monochrome device (of late: an e-ink tablet with Termux
         | installed for a Linux userland).
         | 
         | On Linux, if something annoys you, _there 's almost always an
         | alternative or configuration to alleviate that_.
        
       | LordShredda wrote:
       | > No colours
       | 
       | > What? I see green.
       | 
       | Smart ass bear. Good article as always.
       | 
       | Colored output feels like something a syscall should handle.
       | Something like setcolor, unsetcolor, separate from the typical
       | printf functions. At least escape sequences are easy to detect
       | and remove, albeit a hassle.
        
         | zokier wrote:
         | Trying to remove control codes reminds me of this answer:
         | https://superuser.com/a/1388860
         | 
         | and then I shudder and walk away.. the variety in the answers
         | is alone a thing to wonder
        
         | icedchai wrote:
         | It seems a bit high level for a syscall. Perhaps you're looking
         | for a library, like terminfo?
         | https://stackoverflow.com/questions/42734416/how-to-set-colo...
        
       | TacticalCoder wrote:
       | > Look at that, it's even doing memoization!
       | 
       | That function takes no argument. I've never seen initializing a
       | single variable and returning the result of that initialized
       | variable from a function call taking no argument called
       | "memoization".
       | 
       | Memoization is a specific type of caching with a space/time
       | trade-off where the result of a particular (set of) input(s) are
       | cached.
       | 
       | I find it quite a stretch to call initializing a single integer
       | for a function taking no parameters "memoization". I'd just say
       | the function's return value is "cached".
       | 
       | I mean: by kinda, sorta, bending the definition of memoization
       | (for example by changing "caching the function's results based on
       | the inputs" to "caching the only result for there's no input to
       | the function") you could say that it is actually memoization but
       | then I'd argue this is not a great example of what memoization
       | is.
       | 
       | I may be wrong though.
        
         | fasterthanlime wrote:
         | I mean it's a perfectly fine hill to die on, but I think
         | "memoization for n=0 arguments" is cromulent. Or even
         | "memoization for n=1 argument, which only has one possible
         | value" (like a unit enum in Rust). I could see both positions
         | being justifiable tbqh.
        
           | TacticalCoder wrote:
           | You guys may be right. I really honestly never ever thought
           | it that way.
           | 
           | No hill to die on (and I enjoyed TFA!) that said ^ ^
        
         | quesera wrote:
         | Wikipedia say:
         | 
         | > an optimization technique used primarily to speed up computer
         | programs by storing the results of expensive function calls and
         | returning the cached result when the same inputs occur again
         | 
         | "the same" could be none, default, or null, I think.
        
       | dvh wrote:
       | I have to strongly disagree with "useless use of cat". Using cat
       | first have 3 main advantages making it vastly superior:
       | 
       | 1. It allows you to drop context quickly and focus on algorithm.
       | You write "cat filename" and you can free your mind and focus on
       | the rest of the pipes. Without cat, you have to keep filename in
       | your mind while you write the first command.
       | 
       | 2. It puts filename closer to the beginning so when you need to
       | repeat for few more files, you just press home and one
       | Ctrl+right, whereas without cat, you would have to move several
       | times right depending on how many switches first command needed
       | which is always random. Plus most of the back and forth switch
       | editing will be in the first command and filename would just get
       | in the way.
       | 
       | 3. It works the same for every app. Some apps need file as last
       | parameter, some needs -i, or whatever switch, some use some other
       | random scheme. Cat is always the same.
        
         | arendtio wrote:
         | I also like 'cat file | ...' pattern better, but I can also
         | understand people who say that using the '<file ...' pattern is
         | cleaner.
         | 
         | So as long as people don't cry 'useless use of cat' we get
         | along ;-)
        
         | emeraldd wrote:
         | I honestly have to agree ... I tend to use cat because I don't
         | always know what the next thing in my pipeline is going to be
         | and frequently change out later steps in the pipeline. Putting
         | the real first operation in place of cat means it's harder to
         | reuse a particular idiom or "stage" parts of a pipeline that
         | might be slow in a temp file while you're figuring out how to
         | string things together.
        
         | vsviridov wrote:
         | I build pipes left to right, and I read pipes left to right...
         | 
         | 1 -> 2 -> 3 is easier that (2 <- 1) -> 3
        
           | throwaway173738 wrote:
           | This is also the classic argument against reverse polish
           | notation. Operator-first makes it harder to say the name of
           | an operator in a sentence.
        
             | ajuc wrote:
             | Reverse polish notation is operator last.
        
             | jrockway wrote:
             | Infix operators are very weird, though. They come from
             | math, where every elementary school student has to memorize
             | "please excuse my dear aunt sally" to be able to answer a
             | simple question like "what is 23 + 4 / 2". C copied this
             | concept, and nobody really ever bothered to memorize C's
             | operator precedence, so they just end up writing Lisp but
             | with the operators in the middle. pow(2, 3) + (4/2). Note
             | that some operators appear prefix instead of infix for no
             | apparent reason.
             | 
             | (You can't just remember what you learned in math class
             | when writing a computer program, because now we have
             | bitwise and, or, xor, left shift, right shift, equality,
             | pointer dereferencing, assignment, logical and, or, modulo,
             | pre-increment, post-increment, bitwise not, logical not,
             | etc. So you have to learn it all again. And it's different
             | for every language.)
             | 
             | Put everything up front, and suddenly you don't have to
             | think about this anymore. (+ (expt 2 3) (/ 4 2)). The
             | computer just does what you say and there are no rules to
             | memorize.
             | 
             | Personally, I always use RPN calculators (dc is my
             | favorite), because I don't trust the calculator to remember
             | operator precedence. They usually do it right, but it's
             | difficult to reason about. (The example would be "2 3 ^ 4 2
             | / + p" in dc.)
        
           | samsquire wrote:
           | You can put shell file redirections such as "< file" at the
           | beginning of the line.
           | 
           | In bash, type:                  < /etc/resolv.conf grep
           | nameserver
           | 
           | (That < is not a prompt, that's the less than symbol)
        
             | kzrdude wrote:
             | Nice, I learned something and thank you
        
             | tolciho wrote:
             | Sometimes you can prefix with "< file". Sometimes, not so
             | much.
             | 
             | < /etc/passwd while IFS= read line || [ -n "$line" ]; do
             | printf '%s\n' "$line"; done
             | 
             | Meanwhile, in ZSH...
             | 
             | Meanwhile, in languages that do not need IFS= and || [ -n
             | "$line" ] checks...
        
             | ilyt wrote:
             | aliasing c to cat still requires less keystrokes
        
         | xorvoid wrote:
         | I came here to say the same haha.
         | 
         | It's like an "article" or "preposition" in English. Arguably
         | not required, but in practice invaluable. One could argue that
         | shell could have been designed better to not need it but, meh,
         | that ship sailed. Uses of "cat" are ubiquitous and excellent.
         | Not sure why people remotely care when there are bigger
         | problems to worry about.
        
         | lucideer wrote:
         | There was a recent thread on HN about generating HTML using
         | string templates, arguing that if users keep on doing something
         | for years despite constant recommendations against it, the
         | recommendations must be wrong.
         | 
         | I didn't agree with it - it's an ok rule of thumb in moderation
         | but I don't think HTML string templates are a good example.
         | But, `cat` is absolutely the perfect example.
         | 
         | I use shellcheck which automatically corrects all my "useless"
         | uses of cat, and I can tell you there's no more common error in
         | other people's code that it complains about. And the benefits
         | of "fixing" this error are always so marginal, the resultant
         | code so much less readable.
        
         | paulddraper wrote:
         | < file command
         | 
         | Is perfectly valid.
         | 
         | To me, it just makes sense to put input on the left of a
         | pipeline.
         | 
         | IDK why others don't, but :shrug:
        
         | dllthomas wrote:
         | These advantages are generally shared by simply opening with
         | "<filename" instead of "cat filename |".
        
         | sverona wrote:
         | A good friend of mine called "cat file.txt" UUOC on the grounds
         | I should have run "less file.txt". If you're writing a script,
         | sure. If it's the first step in a pipeline that you're typing
         | on the fly, does it really matter?
        
           | levihaku wrote:
           | cat file.txt is always worthless. Best case scenario, you
           | will end up with text that fits into one scree, but more
           | often than not you will have to retype the command with
           | $EDITOR filename or less filename anyway and now you just
           | wasted (precious) time doing what could've been done few
           | seconds ago.
           | 
           | Sure, few seconds isn't a lot, to someone who opens terminal
           | once a year.
        
             | omnibrain wrote:
             | Depends on how your terminal(-emulator) behaves in
             | conjunction with the scroll lock key.
        
             | bloopernova wrote:
             | After your cat command has run, type 'vim ' then hit the
             | escape key plus the period/full stop key. That inserts the
             | previous command's parameters/arguments at the cursor.
             | 
             | Obviously you don't have to use vim, any other editor or
             | whatever can be used.
        
               | quesera wrote:
               | > _inserts the previous command 's parameters/arguments
               | at the cursor_
               | 
               | In zsh, there are equivalent expansions:
               | !!:1    previous command line, arg 1 (zero-indexed)
               | !!:$    previous command line, LAST arg       !!:1-$
               | previous command line, args 1-end (zero-indexed)
               | 
               | So, e.g.:                 cat /etc/passwd /etc/shadow
               | /etc/group            vi !!:1-$
               | 
               | (becomes)                 vi /etc/passwd /etc/shadow
               | /etc/group
        
               | bloopernova wrote:
               | Nice! I'll have to add those to my wall of index cards
               | with useful commands.
        
               | quesera wrote:
               | I use !!:$ occasionally.
               | 
               | If I wanted to do the cat/vim switcheroo you described,
               | I'd more likely do:
               | <UpArrow><Esc>vcwvi<Esc>:wq<Enter><Enter>
               | 
               | Which is a greater number of keypresses, but more
               | flexible and requires less thought.
               | 
               | ...as they say: _Unix is user-friendly -- it 's just
               | choosy about who its friends are._
        
             | tedunangst wrote:
             | cat file leaves the contents on my screen as I compose my
             | next shell command, as opposed to erasing them as quitting
             | the editor flips back from the alt screen.
        
               | quesera wrote:
               | I sometimes use the following prevent screen clearing
               | when exiting vi:                 :set t_te=
               | 
               | Useful because vi makes it more convenient to select the
               | chunk of file I want to view after exiting. More
               | convenient than cat/head/tail at least. Competitive with
               | more. :)
        
             | pxc wrote:
             | If you're using a terminal multiplexer to handle
             | scrollback, you can navigate the output using your usual
             | pager whether you explicitly invoked it in the pipeline or
             | not. And that leaves it searchable in your scrollback
             | history even after you've gone on to run several more
             | commands, unlike if you pipe it directly to a pager.
             | 
             | Additionally, if you're using a nicer colorizing pager,
             | like bat, it'll automatically send the output to your pager
             | for you when it detects that the output wouldn't fit on
             | screen.
             | 
             | For both of those reasons, I almost never use `less`
             | directly on a file.
        
               | darkwater wrote:
               | First case is good, the second one feels like cheating,
               | if you are using a cat substitute like bat, well, you are
               | not using cat already.
        
               | pxc wrote:
               | Fair enough :)
        
         | ilyt wrote:
         | It's just OCD people not having anything to bitch about in
         | life. But to add to the point:
         | 
         | 4. You are just ctrl-a away from changing source
         | 
         | the common use for me for example                   cat f.log
         | |grep sth # okay it shows in history; C-a         tail -f f.log
         | | grep sth # let's try to repeat it live; C-a         zcat
         | f.log.1.gz | grep sth # no dice, let's try to dig a bit in
         | history
        
         | alex_smart wrote:
         | I have honestly not seen a more egregious case of "premature
         | optimization". Who the fuck cares about 1% extra performance on
         | something they are doing on the interactive shell? (And the
         | answer wouldn't even change if the performance difference was
         | 100%.)
         | 
         | What an utterly useless thing to get pedantic about.
        
         | gorgoiler wrote:
         | Not that it really matters, but on your second point:
         | $ <example.json jq       [         1,         2,         3
         | ]
         | 
         | ...but if you are using a POSIXish shell, which I do not
         | (fish).
        
       ___________________________________________________________________
       (page generated 2023-05-29 23:00 UTC)