[HN Gopher] Shell Tricks That Make Life Easier (and Save Your Sa...
       ___________________________________________________________________
        
       Shell Tricks That Make Life Easier (and Save Your Sanity)
        
       Author : zdw
       Score  : 503 points
       Date   : 2026-03-26 00:28 UTC (22 hours ago)
        
 (HTM) web link (blog.hofstede.it)
 (TXT) w3m dump (blog.hofstede.it)
        
       | zahlman wrote:
       | Not a fan of the LLM-flavoured headings, and the tips seem like a
       | real mixed bag (and it'd be nice to give credit specifically to
       | the readline library where appropriate as opposed to the shell),
       | but there are definitely a few things in here I'll have to play
       | around with.
       | 
       | One thing I dislike about brace expansions is that they don't
       | play nicely with tab completion. I'd rather have easy ways to
       | e.g. duplicate the last token (including escaped/quoted spaces),
       | and delete a filename suffix. And, while I'm on that topic,
       | expand variables and `~` immediately (instead of after pressing
       | enter).
        
         | ta8903 wrote:
         | Speaking of readline, I recently found out PowerShell has a
         | readline mode (https://learn.microsoft.com/en-
         | us/powershell/module/psreadli...) and it works great.
         | 
         | As someone who works mostly in WSL and has to use PS
         | occasionally, it really reduces the overhead of the context
         | switch.
        
         | umanwizard wrote:
         | Readline is close enough to being part of bash that it's not
         | really inaccurate to call these all shell features imo.
        
           | integralid wrote:
           | Except not everyone uses bash shell - so it's not really
           | accurate.
        
         | croemer wrote:
         | Not just the heading is LLM-flavoured. So is the writing, e.g.
         | "The shell is a toolbox, not an obstacle course."
        
           | zahlman wrote:
           | Yeah, there are a few of those, but overall there wasn't
           | really _enough_ prose in total to really irritate me. And
           | those LLM-isms do come from somewhere, and I really do get
           | the sense that some humans are effectively training
           | themselves off of AI now.
        
       | aa-jv wrote:
       | My favourite shell trick is to comment my code:                 $
       | some_long_command -with -args -easily -forgotten #
       | thatspecialthing
       | 
       | ... Some weeks later ..                 $ CTRL-R<specialthing>
       | 
       | .. finds:                 $ some_long_command -with -args -easily
       | -forgotten # thatspecialthing
       | 
       | Need to see all the special things you've done this
       | week/whenever?                 $ history | grep "\#"
       | 
       | ...
       | 
       | Makes for a definite return of sanity ..
        
         | senectus1 wrote:
         | omg >$ CTRL-R<specialthing>
         | 
         | I could kiss you.. this alone is amazing!
        
           | aa-jv wrote:
           | Yes indeed, it is very fun to discover this if you don't know
           | it already, it expands your understanding of your shell life
           | immensely, doesn't it?
        
           | fragmede wrote:
           | http://atuin.sh adds a database to store history in and a
           | custom app to use for lookup with added modes to help with
           | searching.
        
           | 000ooo000 wrote:
           | !?specialthing?
           | 
           | If you are feeling brave
        
         | skydhash wrote:
         | I don't keep history. Any commands I think will be useful, I
         | save it in a script.
        
         | scbrg wrote:
         | I once saw this pattern referred to as a bashtag, which I think
         | was an excellent name (no matter if you actually run bash as
         | your shell or not).
        
       | tetris11 wrote:
       | Never heard of instant truncate, nor `fc`, nor `Esc .`
       | 
       | Quite a few useful ones
        
       | chasil wrote:
       | A much larger base for ksh (as a pdksh descendent) is Android.
       | OpenBSD is a tiny community in comparison, although Android has
       | acquired code directly from OpenBSD, notably the C library.
       | 
       | The vi editing mode is always present in ksh, but is optional in
       | dash. If present, the POSIX standard requires that "set -o vi"
       | enable this mode, although other methods to enable it are not
       | prohibited (such as inputrc for bash/readline), and as such is a
       | "universal trick."
       | 
       | The article is relying on some Emacs mode, which is not POSIX.
       | 
       | $_ is not POSIX if I remember correctly.
       | 
       | History in vi mode is easier, just escape, then forward slash (or
       | question mark) and the search term (regex?), then either "n" or
       | "N" to search the direction or its reverse.
       | 
       | I've seen a lot of people who don't like vi mode, but its
       | presence is the most deeply standardized.
        
       | fellerts wrote:
       | CTRL + W usually deletes everything until the previous
       | whitespace, so it would delete the whole '/var/log/nginx/' string
       | in OP's example. Alt + backspace usually deletes until it
       | encounters a non-alphanumeric character.
       | 
       | Be careful working CTRL + W into muscle memory though, I've lost
       | count of how many browser tabs I've closed by accident...
        
         | gryfft wrote:
         | Ctrl-Shift-T usually brings that tab right back at least
        
         | hejira wrote:
         | In my terminal it's the exact opposite - Alt-Backspace deletes
         | to the previous space, whereas Ctrl-W deletes to the last non-
         | alphanumeric (such as /). I'm using fish shell in an Alacritty
         | terminal.
         | 
         | Yeah, pressing Ctrl-W accidentially is a pain sometimes ... but
         | Ctrl-Shift-T in Firefox is a godsend.
        
           | Aerolfos wrote:
           | > Yeah, pressing Ctrl-W accidentially is a pain sometimes ...
           | but Ctrl-Shift-T in Firefox is a godsend.
           | 
           | Fun fact: despite having absolutely no menu entry for it, and
           | I believe not even a command available with Ctrl+Shift+P,
           | Vscode supports Ctrl+Shift+T to re-open a closed tab.
           | Discovered out of pure muscle memory.
        
             | dgrunwald wrote:
             | It's a normal command called "View: Reopen Closed Editor".
        
         | figmert wrote:
         | > Be careful working CTRL + W into muscle memory though, I've
         | lost count of how many browser tabs I've closed by accident...
         | 
         | This hurts.
         | 
         | Also, for the shell, if you do C+w, you can "paste" it back
         | using C+y. Assuming you have not removed that configuration.
        
         | fainpul wrote:
         | Set $WORDCHARS accordingly. In your case, remove / from
         | $WORDCHARS.
         | 
         | https://unix.stackexchange.com/a/726014
        
           | exceptione wrote:
           | For the bash people                 stty werase undef
           | bind '"\C-w": backward-kill-word'
           | 
           | source: https://superuser.com/questions/212446/binding-
           | backward-kill...
        
         | fp64 wrote:
         | I've installed "More Better Ctrl-W" for Chromium, and mapped
         | Ctrl-W to do nothing, and Ctrl-D to close the current tab
        
           | arcanemachiner wrote:
           | But how am I supposed to create or edit a bookmark?
        
         | sfink wrote:
         | ...which is why I recently went to about:keyboard and removed
         | that hotkey. I love that page.
         | 
         | That, and Ctrl-N. No more forest of blank browser windows when
         | using a terminal emulator in a web page!
         | 
         | (Firefox only)
        
           | naikrovek wrote:
           | Ctrl+W is undoable.
           | 
           | Ctrl+Shift+T will undo your recent tab closures in reverse
           | order. The tabs maintain their history as well.
           | 
           | I am very surprised at how many people in here don't seem to
           | know that. I learned about Ctrl+Shift+T before I learned
           | about Ctrl+W. I was using the middle mouse button on a tab to
           | close tabs before then.
        
             | sfink wrote:
             | I know. I used to use it fairly often when Ctrl-W still did
             | something. It helps, but (1) it doesn't work if you closed
             | the last tab and thus the whole window, you'd need to
             | restore recently closed windows instead; and (2) it is
             | still more disruptive and potentially state-losing than
             | preventing an unwanted close in the first place. Tab
             | history retention isn't perfect.
        
         | oxag3n wrote:
         | Depends on the shell - bash on my Ubuntu deletes entire
         | '/var/log/nginx/', while after switching to sh it deletes only
         | nginx
        
         | themafia wrote:
         | 'man readline' contains all the useful key combinations.
        
         | lelanthran wrote:
         | > Be careful working CTRL + W into muscle memory though, I've
         | lost count of how many browser tabs I've closed by accident...
         | 
         | You're telling me!!!
         | 
         | (I use vim daily, with multiple splits in a single instance.)
        
           | naikrovek wrote:
           | CTRL+SHIFT+T will resurrect your most recently closed tab,
           | with history. Pressing it again will bring up the next most
           | recently closed tab, with history. Etc.
           | 
           | Or maybe you don't use SHIFT. Can't recall right now. My
           | fingers know but I'm not at a computer.
           | 
           | Anyway, browser menus can also show you recently closed tabs
           | and bring them back.
        
         | goplayoutside wrote:
         | Firefox v147 finally added the ability to redefine keyboard
         | shortcuts, including ^w:
         | https://news.ycombinator.com/item?id=46952095
         | 
         | 1. Load about:keyboard
         | 
         | 2. Find "Close tab" and click "Clear" or "Change".
        
         | meatmanek wrote:
         | > Be careful working CTRL + W into muscle memory though, I've
         | lost count of how many browser tabs I've closed by accident...
         | 
         | I still maintain this is why macOS is the best OS for terminal
         | work -- all the common keybindings for GUI tools use a
         | different modifier key, so e.g. [?]C and [?]W work the same in
         | your terminal as they do in your browser.
         | 
         | (Lots of the readline/emacs-style editing keybindings work
         | everywhere in macos as well -- ^A, ^E, ^K, ^Y, but not ^U for
         | some reason)
        
       | Joker_vD wrote:
       | > The "Works (Almost) Everywhere" Club
       | 
       | > The Backspace Replacements
       | 
       | Also known as "emacs editing mode". Funnily enough, what POSIX
       | mandates is the support for "vi editing mode" which, to my
       | knowledge, almost nobody ever uses. But it's there in most
       | shells, and you can enable it with "set -o vi" in e.g. bash.
        
         | ZeroGravitas wrote:
         | Vi mode is also available in Claude code and gemini-cli to give
         | some recent examples, and a bunch of other places you might not
         | expect it, as well the more obvious places where code is
         | written.
         | 
         | Once you get used to it, it is painful to go back.
        
           | mr_mitm wrote:
           | My biggest complaint about the fish shell is the lack of true
           | vi mode. They attempt to emulate it and it works to some
           | degree, but it's no comparison to readline's implementation.
        
             | maleldil wrote:
             | You can always use Alt-E to open the command line in
             | $EDITOR if you need more powerful commands. I find it
             | better to use readline for small changes and jumping to vim
             | for bigger ones.
        
             | umanwizard wrote:
             | Have you tried a recent version? An issue I opened about
             | this years ago was finally closed, they claim it's fixed
             | now. I haven't tried the purported fix, though.
        
               | mr_mitm wrote:
               | Yes. It has improved, but it's still not there, and
               | probably never will be. See my reply to your sibling
               | comment.
        
             | dunb wrote:
             | What is it lacking in your eyes that makes it not true? I
             | find fish's vi mode more ergonomically complete for things
             | like editing multi-line commands
        
               | mr_mitm wrote:
               | Just pressing `xp` to swap two characters does not work
               | in fish. Combining deletion with a movement also does not
               | work (e.g. `d3w` to delete three words).
        
         | worksonmine wrote:
         | And if you set `set editing-mode vi` in ~/.inputrc (readline
         | configuration) you'll have it in even more places.
        
       | voidUpdate wrote:
       | With ctrl+r, if you press it twice, it will autofill the search
       | with whatever you last searched for. pressing it more will go
       | back through the history. Been using that a lot recently when
       | doing docker stuff. ctrl+r, type the container name, keep going
       | until I get the compose build command. ctrl+r, ctrl+r, repeat
       | until the log command. Then I can just mash ctrl+r to get the
       | build and log commands. Ctrl+r is your friend. ctrl+r
        
         | arcanemachiner wrote:
         | Make sure to add fzf + shell integration for maximum Ctrl+r
         | goodness.
        
           | ZeroGravitas wrote:
           | Also worth reading the intro to fzf search syntax.
           | 
           | https://junegunn.github.io/fzf/search-syntax.
           | 
           | The $ and bang and exact search are neat, but the bit at the
           | bottom as to why `gadd` or `gas` is a better search for `git
           | add something` than something with full words and spaces is a
           | revelation when first using fzf.
        
       | tkocmathla wrote:
       | I love this, from a comment on the article:                 He
       | had in his path a script called `\#` that he used to comment out
       | pipe elements like `mycmd1 | \# mycmd2 | mycmd3`. This was how
       | the script was written:             ```       #!/bin/sh       cat
       | ```
        
         | internet_points wrote:
         | Yes! That one's going in my $PATH. Such a useful use of cat!
        
         | rgrau wrote:
         | A similar trick:                   #!/bin/sh         $*
         | 
         | that's my `~/bin/noglob` file, so when I call a zsh script from
         | bash that uses `noglob`, it doesn't blow up.
        
         | 000ooo000 wrote:
         | What does it provide over
         | 
         | mycmd1 #| mycmd2
        
           | chriswarbo wrote:
           | Theirs "turns off" one element of a pipeline; yours turns off
           | everything after a certain point.
           | 
           | This will output the stdout of mycmd1:
           | mycmd1 #| mycmd2 | mycmd3
           | 
           | This will output the stdout of mycmd3:
           | mycmd1 | \# mycmd2 | mycmd3
        
             | mkoryak wrote:
             | Can you explain to me why either of these is useful?
             | 
             | I've somehow gotten by never really needing to pipe any
             | commands in the terminal, probably because I mostly do
             | frontend dev and use the term for starting the server and
             | running prodaccess
        
               | agons wrote:
               | I can imagine a pipeline where intermediate stages have
               | been inserted to have some side effect, like debug
               | logging all data passing through.
        
               | chriswarbo wrote:
               | Pipelines are usually built up step by step: we run some
               | vague, general thing (e.g. a `find` command); the output
               | looks sort of right, but needs to be narrowed down or
               | processed further, so we press Up to get the previous
               | command back, and add a pipe to the end. We run that,
               | then add something else; and so on.
               | 
               | Now let's say the output looks wrong; e.g. we get nothing
               | out. Weird, the previous command looked right, and it
               | doesn't seem to be a problem with the filter we just put
               | on the end. Maybe the filter we added part-way-through
               | was discarding too much, so that the things we actually
               | wanted weren't reaching the later stages; we didn't
               | notice, because everything was being drowned-out by
               | irrelevant stuff that that our latest filter has just
               | gotten rid of.
               | 
               | Tricks like this `\\#` let us turn off that earlier
               | filter, without affecting anything else, so we can see if
               | it was causing the problem as we suspect.
               | 
               | As for more general "why use CLI?", that's been debated
               | for decades already; if you care to look it up :-)
        
               | mkoryak wrote:
               | no no, not asking why use CLI. If I was less lazy, I
               | would use it more often
        
             | 000ooo000 wrote:
             | Ah duh, cheers
        
         | mzs wrote:
         | Wow I hate* that. I use bracket comments. They're cool cause
         | they are bracket comments, so I use it in scripts to document
         | pipelines. They are annoying cause they are bracket comments,
         | in an interactive shell I have to type more and in TWO places.
         | It's fun to reason-out how it works ;)                 $ echo
         | foo | tr fo FO | sed 's/FOO/BAR/'       BAR       $ echo foo |
         | ${IFS# tr fo FO | } sed 's/FOO/BAR/'       foo
         | 
         | It's nice to have a way to both /* ... */ and // ... in shell
         | scripts though:                 foo \       | bar ${IFS Do the
         | bar. Do it. } \       | baz
         | 
         | * in the best possible way, like it's awful - I hate I didn't
         | think of that
        
           | rgrau wrote:
           | for multiline pipes, it's WAY better to format like
           | foo   |           bar |           baz
           | 
           | You don't have to use backquotes, AND, it allows you to
           | comment line by line, because there's no backslash messing
           | with the parser.
           | 
           | I also use a last `|\ncat` so you can delete any line and you
           | don't have to worry about the last line being a bit different
           | than the rest
           | 
           | I created a list of similar tricks in
           | https://github.com/kidd/scripting-field-guide in case anyone
           | wants to take a look
        
             | mzs wrote:
             | You'll probably dislike this too:                 $ {
             | >     echo foo \       >     && echo bar \       >     ||
             | echo baz ;       > }       foo       bar
             | <^P><^A>$<^F>IFS       ${IFS#   echo foo   && echo bar   ||
             | echo baz ; }       $ _
             | 
             | There's good and bad to both approaches. I like how I can
             | use () and {} to bracket things and otherwise every line
             | that end in \ is continued. I line-up on the left with the
             | operator, you with indentation. When you use a # style
             | comment, you have to look up and back and forward to see
             | what the operator is you are continuing over to the next
             | line:                 $ foo |         bar | # ?Do? *the*
             | $bar$ && [do] {it!}         baz
             | 
             | Which only takes an extra neuron or so, but then history...
             | <^P>       $ foo |   bar | # ?Do? *the* $bar$ && [do] {it!}
             | baz
        
               | rgrau wrote:
               | aha! I see what you mean, it's indeed a nice option, yep.
               | 
               | Using brackets like this is something I never thought of,
               | and it's probably why it's hard for me to process it, but
               | I can see it provides nice annotation capabilities, and
               | it's a more self-contained style.
               | 
               | Thx for sharing!
        
       | talkin wrote:
       | > cd -: The classic channel-flipper. Perfect for toggling back
       | and forth.
       | 
       | And not only cd. Gotta love 'git checkout -'
        
         | piekvorst wrote:
         | The '-' shortcut is weird. In 'git commit -F -', the '-' is
         | actually /dev/stdin.
        
           | account42 wrote:
           | - is a pretty standard idiom for using stdin/stdout instead
           | of a named file that you can find in many commands. I don't
           | think it conflicts with the cd/checkout usage though as there
           | the argument normally does not refer to a file so having -
           | mean stdin/stdout doesn't make sense.
        
           | mpyne wrote:
           | `-` is the traditional shell way to refer to stdin/stdout (as
           | with your git commit example) but also the traditional way to
           | refer to the last directory you were in (as with git
           | checkout/switch).
           | 
           | You would never pipe the output of a command to `cd` so the
           | `-` shortcut couldn't be helpful to cd as-is. So rather than
           | invent yet another shortcut to memorize for `cd` they reused
           | the existing one which otherwise would be redundant, which I
           | appreciate at least.
           | 
           | But git is simply being consistent with the shell to further
           | reduce the cognitive complexity of reusing shell commands
           | you're used to in analogous git contexts.
        
       | faangguyindia wrote:
       | I just open, agent in tui, and ask it to do what I want and make
       | a plan, i read the plan edit it and run it.
       | 
       | Simple, no need to learn any commandline these days.
       | 
       | I used to use arch and all, and managed many big projects. I find
       | little value in learning new tools anymore, just feed it docs and
       | it generated working plan most of the time
       | 
       | Now I've moved to coding in Haskell, which i find suits me better
       | than wasting my time with cli and exploring what options all
       | these cli tools have.
        
         | worksonmine wrote:
         | What is it like to be this proud of not learning the tools you
         | use? Do you really think several paragraphs to an agent that
         | may or may not be correct is the "easy" way compared to just
         | checking the manual for the flag you want?
         | 
         | I will never understand people like you.
        
           | faangguyindia wrote:
           | Tools are means to end.
           | 
           | They don't matter much to me.
        
         | chriswarbo wrote:
         | I'm confused; how is writing a shell command (using shortcuts
         | like those in the article!) "wasting time", but describing what
         | you want to an LLM, having it make a plan, reading the plan,
         | editing it, and running it is somehow _not_ a waste of time?
         | 
         | You also mention there being "little value", when your proposed
         | approach costs literal money in form of API/token usage (when
         | using hosted models).
         | 
         | > Now I've moved to coding in Haskell
         | 
         | You might like https://hackage.haskell.org/package/turtle or
         | http://nellardo.com/lang/haskell/hash/
        
       | ahmedfromtunis wrote:
       | Using the terminal becomes much more cozy and comfortable after I
       | activate vim-mode.
       | 
       | A mistake 3 words earlier? No problem: <esc>3bcw and I'm good to
       | go.
       | 
       | Want to delete the whole thing? Even easier: <esc>cc
       | 
       | I can even use <esc>v to open the command inside a fully-fledged
       | (neo)vim instance for more complex rework.
       | 
       | If you use (neo)vim already, this is the best way to go as there
       | are no new shortcuts to learn and memorize.
        
         | rzmmm wrote:
         | Oh wow I didn't know about this, thank you. The underlying
         | feature is called "readline vi-mode" for folks who want to
         | search more about it.
        
         | commandersaki wrote:
         | I've been a (n)vim user for 20+ years now, but I hate vi-mode
         | in the shell. However if I feel that I need to do a complex
         | command, I just do ctrl-x+e to open up in neovim (with
         | EDITOR=nvim set). I find it a good middle ground.
        
           | sudonem wrote:
           | Agree.
           | 
           | I WANT to love it - and if I was only ever working on one, or
           | a small number of systems that I was the only one working on
           | I'd probably do it. I'm ALL about customizing my environment.
           | 
           | However ssh into various servers through the day (some of
           | which are totally ephemeral), and having to code switch my
           | brain back and forth between vim mode and emacs mode in the
           | shell would just slow me down and be infuriating each time I
           | connect to a new box.
        
           | xtiansimon wrote:
           | Huh. I don't use vi-mode for more than jumping to the
           | beginning or end of a line, which I like a lot.
        
             | irishcoffee wrote:
             | You mean, like the "home" and "end" buttons?
        
               | wholinator2 wrote:
               | Yeah but those are so far away, i have to hunt for them
               | every time
        
             | wbrd wrote:
             | I'm a vim user but in the shell I use Ctrl-a and Ctrl-e to
             | get to the beginning and end. If I need more editing I use
             | Ctrl-x Ctrl-e to hop into vim.
        
             | void-star wrote:
             | It really shines for navigating history. <esc>/ searches
             | history the same way as the editor search function
        
             | umanwizard wrote:
             | C-a and C-e are your friend.
        
           | busfahrer wrote:
           | I'm the same and in my opinion this is the best of both
           | worlds. Taking the time to learn some of the regular (emacs-
           | style) shortcuts is one of the best investments I've ever
           | done. Even just CTRL+Y and the likes.
           | 
           | edit: And of course, CTRL+R, the best time saver of all
        
           | void-star wrote:
           | It's strange. I have heard this from lots of others too. I
           | think I am an anomaly here. I can't live without shell vi
           | mode
        
             | fp64 wrote:
             | You're not alone, I heavily rely on vi mode and often
             | struggle if I'm on someone else's machine and can't use it.
             | I always wonder how you're supposed to work without it but
             | I never dare to ask
        
               | Linux-Fan wrote:
               | `set -o vi` is quickly typed in anger...
        
             | lenkite wrote:
             | Same - shell vi mode is critical for intensive terminal
             | sessions.
        
             | dbacar wrote:
             | it is an additional burden to switch to shell vi mode, it
             | is not the standard. Maybe you can put it in all of yout
             | bashrc files but you will probably hear some swearing from
             | the people logging to your machines :).
        
           | helterskelter wrote:
           | I used to hate it because I'd sometimes change modes without
           | realizing it, but I began to appreciate it a lot more when I
           | added a mode indicator -- a red 'N' on the rightmost side of
           | the input line.
        
           | looshch wrote:
           | agreed, i use neovim as a terminal multiplexer because vi-
           | mode is really bad. I wrote a blog post on how i solved the
           | issue for myself https://loosh.ch/blog/neovidenal
        
         | exceptione wrote:
         | <esc>3bcw
         | 
         | What is your keyboard layout? This looks like a crime against
         | humanity on a regular qwerty kb.
        
           | sva_ wrote:
           | Instead of esc, type ctrl [
        
             | exceptione wrote:
             | Does it help a lot? You've still got a three to type which
             | is a crime, plus some letters, only to move 3 words. My
             | typing skills are not great, but that sounds like an awful
             | lot of work(?)
             | 
             | If I hit CTRL + ARROW_LEFT 3 times, I am done a lot faster
             | I guess. But I am open to learn, do people really use that
             | and achieve the goal significantly faster?
        
               | gsinclair wrote:
               | I don't love vi-mode, but I'll address your comment.
               | 
               | Many people these days, including yours truly, have caps-
               | lock mapped to ctrl if held or esc if tapped. That's good
               | ergonomics and worth considering for any tech-savvy
               | person.
               | 
               | Instead of the 3b I would type bbb (because I agree with
               | you that typing numerals is a pain).
               | 
               | So (caps lock)bbbcw isn't bad. It's better than it looks,
               | because if you're a vim user then it's just so automatic.
               | "cw" feels like one atomic thing, not two keypresses.
               | 
               | And importantly, it doesn't involve any chords.
        
               | roxolotl wrote:
               | I think it's a difference in how people think. I can't
               | remember hotkeys. It just doesn't compute. But with vim
               | style bindings it's much closer to writing a sentence.
               | `3`, number of times, `b`, beginning of word, `c`,
               | change, `w`, word. Yea it's a lot. I cannot explain why
               | it's simpler for me to learn that than emacs style
               | bindings but it is.
        
               | helterskelter wrote:
               | Obligatory:
               | 
               | Your Problem with vim is you don't grok vi
               | 
               | https://stackoverflow.com/questions/1218390/what-is-your-
               | mos...
        
               | sva_ wrote:
               | We're basically playing a game: if you have to leave
               | homerow hand position, you've lost
        
           | ahmedfromtunis wrote:
           | I use qwerty and azerty, and in both I never felt typing the
           | sequence was any harder than typing any other regular word.
           | Generally speaking, I prefer sequential "shortcuts" then
           | multikey bindings.
        
           | lenkite wrote:
           | Remap Capslock to Esc. Possible in every OS now.
        
         | piekvorst wrote:
         | This reminds me of an excerpt from an old Emacs manual:
         | . . . if you forget which commands deal with windows, just type
         | @b[ESC-?]@t[window]@b[ESC].
         | 
         | This weird command is presented with such a benevolent
         | innocence as if it's the simplest thing in the world.
         | 
         | I think the better advice for command-line editing would be to
         | set up the mouse.
        
           | JadeNB wrote:
           | > This weird command is presented with such a benevolent
           | innocence as if it's the simplest thing in the world.
           | 
           | I think it's a question of context and familiarity. To a vim
           | user, like me and, I assume, ahmedfromtunis, their examples
           | do indeed seem simple and natural. Presumably, to an emacs
           | user, the example you quote (if it's quoted literally--I
           | don't use emacs and can't even tell) is just as natural, and
           | assuming some comfort with emacs is presumably OK in a manual
           | for the software!
        
             | Orygin wrote:
             | > assuming some comfort with emacs is presumably OK in a
             | manual for the software!
             | 
             | How do you get familiar with the software, if the manual
             | expects you to be an expert in it already?
        
               | umanwizard wrote:
               | Not sure if it did at the time, but today emacs comes
               | with a tutorial. You're not expected to learn it by
               | starting on page 1 of the manual.
        
               | Orygin wrote:
               | Why not? I expect to learn how to use a software by
               | reading its manual.
        
               | umanwizard wrote:
               | Surely you _can_ still do that, but starting with the
               | tutorial will be easier and more efficient.
        
               | Pay08 wrote:
               | By reading introductory material.
        
               | noisy_boy wrote:
               | I got familiar with vi by reading a book that had the
               | main vi commands listed out. First learnt how to quit
               | without saving changes, the rest was just practice.
        
             | matthew-craig wrote:
             | The example confusingly includes some weird markup. It's
             | just saying press `ESC-?` then type "window" to search for
             | window commands. These isn't even valid in modern Emacs.
             | The equivalent is `C-h` followed by `a` then type "window".
        
           | mikkupikku wrote:
           | I have yet to see a shell that has mouse enabled line editing
           | support. It should certainly be possible though.
           | 
           | I do prefer vi bindings at the same time though. Vi bindings
           | and mouse support complement each other well, you don't have
           | to choose one or the other, just use whichever feels most
           | natural and convenient in that exact moment.
        
           | gbacon wrote:
           | For a bit about the language, read `3bcw` as move `b`ackward
           | by `3` words and `c`hange the `w`ord under the cursor.
           | 
           | The general form of `b` is `[count]b` where
           | [count] An optional number that may precede the command to
           | multiply                 or iterate the command.  If no
           | number is given, a count of one                     is used,
           | unless otherwise noted.  Note that in this manual the
           | [count] is not mentioned in the description of the command,
           | but only in the explanation.  This was done to make the
           | commands easier to look up.  If the 'showcmd' option is on,
           | the (partially) entered count is shown at the bottom of the
           | window.  You can use <Del> to erase the last digit
           | (|N<Del>|).              b       [count] words backward.
           | |exclusive| motion.
           | 
           | https://vimdoc.sourceforge.net/htmldoc/intro.html#[count]
           | 
           | https://vimdoc.sourceforge.net/htmldoc/motion.html#b
           | 
           | For `c` it's                   ["x]c{motion} Delete {motion}
           | text [into register x] and start
           | insert.  When  'cpoptions' includes the 'E' flag and
           | there is no text to delete (e.g., with "cTx" when the
           | cursor is just after an 'x'), an error occurs and
           | insert mode does not start (this is Vi compatible).
           | When  'cpoptions' does not include the 'E' flag, the
           | "c" command always starts insert mode, even if there
           | is no text to delete.              {motion} A command that
           | moves the cursor.  These are explained in
           | |motion.txt|.  Examples:                      w           to
           | start of next word                      b           to begin
           | of current word                      4j          four lines
           | down                      /The<CR>    to next occurrence of
           | "The"
           | 
           | https://vimdoc.sourceforge.net/htmldoc/change.html#c
           | 
           | https://vimdoc.sourceforge.net/htmldoc/intro.html#{motion}
        
         | penguin_booze wrote:
         | > <esc>cc
         | 
         | Doing control+o in insert mode _temporarily_ places you into
         | normal mode so that you can execute one normal-mode command,
         | and then go back to insert mode again--no need to hit  'i'
         | again.
         | 
         | So, instead of '<esc>cc', '<c-o>S'.
        
           | ahmedfromtunis wrote:
           | The vim version is much easier, if you ask me: 3 strokes, 2
           | keys and 0 combinations.
           | 
           | The one you suggest however requires 4 strokes (ctrl then o
           | then shift then s), 4 keys (ctrl, o, shift, s) and 2
           | combinations.
           | 
           | The "cc" sequence deletes the line and switches automatically
           | to insert mode. To forgo the switch, the sequence then
           | becomes "dd".
        
             | ratrocket wrote:
             | Maybe I have my bash/readline vi mode configured specially
             | to do this, but if I want to delete the entire line and
             | type a new one (from anywhere in that line), I do something
             | simpler than either of these alternatives:
             | 
             | <esc>S
             | 
             | Esc exits insert mode (of course) and capital S erases the
             | line and puts you in insert mode at column 0 (just like in
             | (n)vim, right?).
             | 
             | Like I said, maybe I configured that? But 'S' is standard
             | vim-stuff... (I'm not able to double check my config at the
             | moment).
             | 
             | [Edit: right after hitting submit I realized that my way is
             | perhaps "arguably" simpler because I do have to hit shift
             | to get capital S. So I'm also hitting three keys...]
        
             | maleldil wrote:
             | <c-o>S is also a vim sequence. The equivalent
             | readline/emacs is <c-e><c-u> or <c-a><c-k>, or just <c-u>
             | or <c-k> if you're already at the end/start of the line.
        
           | soraminazuki wrote:
           | Or just <C-u> in insert mode. <C-u> and <C-w> are standard
           | Vim insert mode commands.
           | 
           | https://vimhelp.org/insert.txt.html#i_CTRL-U
        
         | ruptwelve wrote:
         | The <esc>v has been such a lifesaver at times when having to
         | execute/modify super complex commands!
        
         | nidnogg wrote:
         | I've been a vim/nvim casual user for the past year or two, and
         | I still feel as if I'm slightly less proficient in it for the
         | amount of time that I put into it.
         | 
         | I really need to get around to playing with it more. I just
         | hope that especially now with genAI that it's not too late for
         | learning it further.
        
         | dbtc wrote:
         | I use vim a lot but not on the shell
         | 
         | A mistake 3 words earlier?
         | 
         | meta-bbbd (not as elegant, I admit)
         | 
         | delete the whole thing?
         | 
         | ctrl-ak (this is even quicker than vim, especially if capslock
         | is mapped to ctrl)
         | 
         | the control-based emacs movements work system-wide on macos
         | btw. I am using ctrl-p and ctrl-n to go up and down lines,
         | ctrl-a and ctrl-e to go to beginning and end of lines while
         | writing this comment in by browser (which has vimium extension)
         | 
         | Sometimes I wish vim just had full emacs bindings while in
         | insert mode. But I don't like to mess with defaults too much.
         | 
         | I keep thinking I should give vim readline a try though, so
         | maybe today. Thanks for the comment.
        
         | commandlinefan wrote:
         | I've never understood why emacs mode became the default. "set
         | -o vi" is the _first_ command I type in a new shell.
        
           | _doctor_love wrote:
           | remap Caps Lock to Ctrl and see the light from home row
        
         | looshch wrote:
         | i went even further and use neovim as my multiplexer
        
       | ta8903 wrote:
       | Something that should be mentioned is starting a command with a
       | space doesn't add it to your history in most shells, really
       | useful for one-off commands that you don't want cluttering your
       | history.
       | 
       | Also, increase your `$HISTSIZE` to more than you think you would
       | need, there have been cases where it helped me find some obscure
       | command I ran like 3 years before.
        
         | account42 wrote:
         | HISTCONTROL=erasedups can also help keeping more obscure
         | commands in your history, at the expense of context around
         | commands.
        
       | vdm wrote:
       | Ctrl-r works well at searching character trigrams, which can
       | include space. Trigrams without space work well with
       | auto_resume=substring .
       | 
       | `| sudo tee file` when current user does not have permission to
       | >file
        
       | amelius wrote:
       | What confuses me is that Ctrl+Y "yank" means the opposite of what
       | it means in Vim. Certainly does not help with keeping my sanity.
        
         | antiframe wrote:
         | It all depends on your perspective.
         | 
         | Are you yanking into your kill ring or yanking out of your kill
         | ring? I had trouble with yanking and killing until I realized
         | the complement to yanking, killing, only makes sense in the
         | into-the-kill-ring" direction, so yanking must be out of the
         | kill ring.
         | 
         | When I use vim, which I don't think has a kill ring but
         | registers, I think I am yanking into a register and then
         | pasting from a register later.
         | 
         | So, just ask yourself this: "are you using a kill ring or
         | register to store your text?" and the answer becomes clear.
        
         | alex_smart wrote:
         | That is because the terminology (and the keybindings) come from
         | the Emacs tradition, not vim. Most shells come with "vim mode"
         | as well, but at least in my experience, the dual mode editing
         | paradigm of does not feel like a good fit for the shell.
        
       | hikarudo wrote:
       | One trick I use all the time:
       | 
       | You're typing a long command, then before running it you remember
       | you have to do some stuff first. Instead of Ctrl-C to cancel it,
       | you push it to history in a disabled form.
       | 
       | Prepend the line with # to comment it, run the commented line so
       | it gets added to history, do whatever it is you remembered, then
       | up arrow to retrieve the first command.
       | 
       | $ long_command
       | 
       | <Home, #>
       | 
       | $ #long_command
       | 
       | <Enter>
       | 
       | $ stuff_1 $ stuff_2
       | 
       | <Up arrow a few times>
       | 
       | $ #long_command
       | 
       | <home, del>
       | 
       | $ long_command
        
         | fragmede wrote:
         | Fwiw, in Bash, alt-shift-3 will prepend the current command
         | with # and start a new command.
        
           | j4cobgarby wrote:
           | More generally, it's alt-#. On an ISO (e.g. UK) keyboard
           | layout, shift-3 isn't a hash.
        
         | gvalkov wrote:
         | In zsh you can bind "push-line-or-edit". In bash and all
         | readline programs, you can approximate it with C-u followed by
         | C-y (i.e. cut and paste). My history is still full of '#' and
         | ':' (csh trauma) prefixed command-lines like you described
         | though ...
        
         | idoubtit wrote:
         | You missed an easier alternative that was in the article:
         | ctrl-u saves and clears the current line, then you can input
         | new commands, then use ctrl-y to yank the saved command.
         | 
         | With zsh, I prefer to use alt-q which does this automatically
         | (store the current line, display a new prompt, then, after the
         | new command is sent, restore the stored line). It can also
         | stack the paused commands, e.g.:
         | 
         | $ cp foo/bar dest/ <alt-q>
         | 
         | $ wcurl -o foo/bar "$URL" <alt-q>
         | 
         | $ mkdir foo <enter> <enter> <enter>
        
           | philsnow wrote:
           | When you're killing (C-u, C-k, C-w, etc) + yanking (C-y), you
           | can also use yank-pop (bound to M-y in bash and zsh by
           | default) to replace the thing you just yanked with the thing
           | you had killed before it.                 $ asdf<C-w>       $
           | # now kill ring is ["asdf"]       $ qwerty<C-a><C-k>       $
           | # now kill ring is ["qwerty", "asdf"]       $ <C-y>
           | # "yank", pastes the thing at the top of the kill ring
           | $ qwerty<M-y>      # "yank-pop", replaces the thing just
           | yanked with the next                          # thing on the
           | ring, and rotates the ring until the next yank       $ asdf
        
       | quijoteuniv wrote:
       | Guilty as charged
        
       | nasretdinov wrote:
       | I'd advise against using sudo !! though since it adds the command
       | to history and then it's very easy to accidentally trigger,
       | running some undesired command as root without any prior
       | confirmation. IMO pressing up, Ctrl-A and typing "sudo " isn't
       | much longer but saves you from running unknown commands as root
       | by accident
        
         | 000ooo000 wrote:
         | I have a bash key binding, Ctrl+Y, that prepends sudo to the
         | current command and submits it. I also don't use sudo-rs. No
         | one has died yet.
        
         | kgwxd wrote:
         | Decades ago, i used a small dns host. I wanted to switch a
         | personal site and they just couldn't get the final step of the
         | transfer to work. A ton of "try now" emails spanning several
         | weeks.
         | 
         | Then one day, I was trying to setup MySQL on a personal Linux
         | machine, and it wouldn't let me use my "standard password" for
         | the admin account. I knew I could just use a different one, but
         | I really wanted to know what the problem was. Took a long time,
         | and I don't remember how I figured it out, but I eventually
         | tracked it to the password ending with '!!'.
         | 
         | It took a while to put it together, and I never confirmed with
         | the dns host support it's what fixed the issue but, I changed
         | my password there, tried the transfer again, and it worked
         | without any help from support. I suspect my plaintext password
         | played some part in a script used in the transfer process, and
         | was outputting the previous command in place of the !! I wish I
         | had asked them if that was it, but if it was, they would have
         | to admit to having my plain text password, or lie about it.
        
         | cocoto wrote:
         | Prepend your command with a space and now your command is not
         | saved in the history.
        
           | sltkr wrote:
           | That depends on the shell configuration.
           | 
           | On bash, you can achieve this by setting
           | HISTCONTROL=ignorespace but that's not the default.
        
         | em-bee wrote:
         | i never found !! useful at all when i can just use up arrow to
         | get the entry i want. it becomes more interesting when you can
         | recall older commands, but then too i prefer search because i
         | want to verify what command i am going to run.
         | 
         | and i only use sudo to open a root shell. never to run anything
         | directly. i don't want normal and root commands mixed in the
         | same history.
         | 
         | i could keep sudo commands out of the history, but then i don't
         | have any history for stuff done as root.
         | 
         | with tmux i can switch terminals easily, so i am also not
         | tempted to run things as root that i shouldn't despite having a
         | root shell open.
        
           | bandie91 wrote:
           | > i want to verify what command i am going to run.
           | 
           | shopt -s histverify
           | 
           | shopt -s histreedit
           | 
           | i dont know why they are not the default.
        
       | commandersaki wrote:
       | My favourite trick is either commenting out a whole command or
       | placing a comment at the end of a command to make it easier to
       | find in my persistent history (thanks eliben) [0], using the #
       | character.
       | 
       | I tried this in zsh and it wasn't the default behaviour which
       | immediately made me nope from the shell altogether, among all the
       | other quirks. I've just been using bash for far too long to
       | switch to something different.
       | 
       | [0] https://eli.thegreenplace.net/2013/06/11/keeping-
       | persistent-...
        
       | amelius wrote:
       | What I hate is that if you start a command with a space it is not
       | recorded in the history. This happens often when copy+pasting
       | commands. I know you can turn it off but still ... this drives me
       | mad.
        
         | frou_dh wrote:
         | AFAIK that setting is opt-in, at least in Bash.
        
           | joombaga wrote:
           | Yeah but some operating systems have HISTIGNORE in (or
           | sourced from) their skeleton files.
        
       | prodigycorp wrote:
       | There's one thing you need to only think about once, and has the
       | potential to save you a _ton_ of time: profile your ZSH startup
       | time!
       | 
       | Stuff like NVM or Oh My ZSH will add a few seconds to your shell
       | startup time.
        
         | sva_ wrote:
         | I can recommend powerlevel10k with instant prompt enabled.
         | 
         | https://github.com/romkatv/powerlevel10k
        
         | chrisweekly wrote:
         | good call
         | 
         | if you care about perf, fnm is better/faster/cleaner than nvm.
         | (also, mise is able to manage "all the things", not just node)
         | 
         | IME omzsh slowness usu relates to overloading it w plugins,
         | which I've never found a need for...
        
         | wewtyflakes wrote:
         | Agreed. I lazy-load NVM to get around that:
         | lazy_nvm() {         unset -f nvm node npm npx         [ -s
         | "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"       }       nvm()
         | { lazy_nvm; nvm "$@"; }       node() { lazy_nvm; node "$@"; }
         | npm()  { lazy_nvm; npm "$@"; }       npx()  { lazy_nvm; npx
         | "$@"; }
        
       | exceptione wrote:
       | I didn't know the `ALT + .` trick to repeat the last argument,
       | but what is even more neat (and not mentioned in the article) is
       | that it cycles through your history. At least it does in my
       | shell.
        
       | keybored wrote:
       | > We've all been there.
       | 
       | Close tab.
       | 
       | I ought to migrate away from shell scripting and just keep the
       | shell for interactive use. Unfortunately I have cursed myself by
       | getting competent-ish with P. shell and Bash scripting. Meaning I
       | end up creating maintenance headaches for my future self.
       | 
       | ( _Echoes of future self: ... so I asked an LLM to migrate my
       | shell scripts to Rust and_ )
       | 
       | Anyway with the interactive shell stuff. Yeah the I guess
       | Readline features are great. And beyond that I can use the
       | shortcut to open the current line in an editor and get that last
       | mile of interactivity when I want it. I don't really think I need
       | more than that?
       | 
       | I tried Vim mode in Bash but there didn't seem to be a mode
       | indicator anywhere. So dropped that.
       | 
       | Edit: I just tested in my Starship.rs terminal: `set -o vi`. Then
       | I got mode indicators. Just with a little lag.
        
         | joombaga wrote:
         | You can use `set vi-ins-mode-string` and `set vi-cmd-mode-
         | string` in .inputrc to get indicators in readline, and you can
         | add them to your prompt with a bit more work:
         | https://superuser.com/questions/1466222/move-vi-mode-string-...
        
       | piekvorst wrote:
       | Is it just me, or is it an LLM language? The article tries very
       | hard to be correct but somehow lacks experience.
       | 
       | I've never used the majority of these tricks for decades, except
       | for brace expansion, process substitutions, and complex
       | redirections.
        
         | xeyownt wrote:
         | I knew many of these tricks, but learned many new tricks I
         | didn't know and looks very useful (like you can do Ctrl-Y after
         | an Ctrl-U, the 'reset' or 'disown' thing).
         | 
         | Regarding experience, I'm also struck by how many "experienced"
         | engineers are just clueless with the keyboard.
        
         | codeinred wrote:
         | I think the keybinding suggestions are really nice. My shell is
         | configured by default such that Alt+Left and Alt+Right move by
         | a word, but having things that work out of the box, basically
         | always, is really useful whenever I need to do things inside a
         | docker container
        
       | fzeindl wrote:
       | My header on top of every script
       | #!/usr/bin/env bash                 set -eEuo pipefail
       | # shellcheck disable=SC2034                 DIR="$( cd "$(
       | dirname "${BASH_SOURCE[0]}" )" && pwd )"
       | #######################################################
        
         | TacticalCoder wrote:
         | Wait... Most of my shell scripts have zero unused variables: I
         | prefer to comment them if I may need them later on.
         | 
         | Why do you disable SC2034?
         | 
         | I don't think not having unused variables prevent me from doing
         | things in my scripts!?
         | 
         | I understand if it's a preference but SC2034 is basically one
         | of my biggest timesavers: in my case unused variables are
         | typically a bug. Except, maybe, ANSI coloring variables at the
         | top of the script.
        
           | fzeindl wrote:
           | I disable it only for the DIR variable which I might not use.
        
         | a-french-anon wrote:
         | I'd suggest `pwd -P` to resolve symlinks too. (if you use DIR
         | to call/source neighbouring scripts).
        
       | teh wrote:
       | Another useful "Emergency exit" is CTRL+Z which stops the process
       | and cannot be intercepted.
       | 
       | It's often faster than hitting CTRL+C and waiting for process
       | cleanup, especially when many resources are used. Then you can do
       | e.g. `kill -9 $(jobs -p)` to kill the stopped tasks.
        
         | drzaiusx11 wrote:
         | ctrl-z pauses the process, it doesn't terminate. I think of z
         | as in zombie as you can then run fg to bring it back from
         | paused state or as you suggested kill in it for good
        
         | dasyatidprime wrote:
         | All of the keyboard-driven terminal signals _can_ be
         | intercepted; catching INT (^C) for cleanup is just more common
         | than the others. Only KILL and STOP cannot be caught.
         | 
         | ^Z sends TSTP (not STOP, though they have the same default
         | behavior) to suspend; some programs catch this to do terminal
         | state cleanup before re-raising it to accept the suspension.
         | Catching it to do full backout doesn't make as much sense
         | because the program anticipates being resumed.
         | 
         | ^\ sends QUIT, which normally causes a core dump and is rarely
         | caught. If you have core dumps disabled (via ulimit -c 0 or
         | other system configuration) then you can often use it as a
         | harder version of ^C; this is how I would tend to get out of
         | 'sl' in places where I found it unwantedly installed.
        
         | tzot wrote:
         | For the most simple case of a single job, I use the job number
         | (`[1]` in the example) with %-notation for the background jobs
         | in kill (which is typically a shell builtin):
         | $ cat         ^Z[1] + Stopped                    cat         $
         | kill %1
        
       | egorfine wrote:
       | I'm using bash for over 30 years and I still find new things.
       | Nice.
        
       | elric wrote:
       | Regarding history: I have a function in my ZSH config which
       | excludes certain things from the history. Especially things that
       | can break stuff when my sausage fingers CTRL-R the wrong thing
       | 
       | Something like this:                   # Prevent certain strings
       | from appearing in the history         # Anything starting with a
       | leading space is ignored         # Anything containing "--force"
       | or "whatever" is ignored         function zshaddhistory() {
       | emulate -L zsh           if ! [[ "$1" =~ "(^ |--force|whatever)"
       | ]] ; then               print -sr -- "${1%%$'\n'}"
       | fc -p           else               return 1           fi
       | }
        
         | rgrau wrote:
         | That's very cool!
         | 
         | To take advantage of the "leading space" one, I have this, to
         | mark some commands that I never want to record:
         | unhist () {              alias $1=" $1"            }
         | unhist unhist            unhist fzf            unhist rghist
         | #custom command that greps .zhistory,...
        
       | 0xcb0 wrote:
       | I've been using a lot of key combinations and I wasn't aware of
       | these two, and I really think these are awesome additions to
       | handling the console. Thank you for showing me. I've only been
       | using it for 22 years, but I haven't come across these :D
       | 
       | `CTRL + U and CTRL + K CTRL + W`
       | 
       | What I like about these key combinations is that they are kind of
       | universal. A lot of programs on Linux and Mac support all these
       | key combinations out of the box. And that's like a game changer
       | in productivity, especially jumping to the start or the end of
       | the line or jumping forward and backward per word is making
       | working only with the keyboard so much more nice. And in editors
       | together so AVY, you can even get a faster flow of jumping
       | around.
        
         | antiframe wrote:
         | Yes, those are shortcuts used in the GNU readline library,
         | which many programs use whenever they need to read lines of
         | text interactively from their operators. Notable examples are
         | (most) shells, (most) interpreters, and tools like ftp, fzf,
         | etc.
         | 
         | Notably, these keybindings are it's default map, which comes
         | from the GNU's project editor Emacs. But, there is also the
         | POSIX-compliant, but not-default, editing mode based on Bill
         | Joy's visual editor (vi).
        
       | williamcotton wrote:
       | Undo:                 Ctrl + _ (Ctrl + underscore)
        
         | bandie91 wrote:
         | it did not work for me in putty, so i added ctrl-x + ctrl-u
         | too:                 bind '"\C-x\C-u": undo'       bind
         | '"\C-_": undo'
        
       | alberto-m wrote:
       | One thing I find life-changing is to remap the up arrow so that
       | it does not iterates through all commands, but only those
       | starting with the characters I have already written. So e.g. I
       | can type `tar -`, then the up arrow, and get the tar parameters
       | that worked last time.
       | 
       | In zsh this is configured with                   bindkey "^[OA"
       | up-line-or-beginning-search # Up         bindkey "^[OB" down-
       | line-or-beginning-search # Down
        
         | heresie-dabord wrote:
         | > life-changing
         | 
         | For further life-changing experience... add aliases to
         | .bash_aliases                   alias gph='history | grep
         | --colour -i '         alias gpc='grep --colour -Hin '
         | #if gnu time is installed         alias timef='/usr/bin/time -f
         | "tm %E , cpu %P , mem %M" '
        
           | TacticalCoder wrote:
           | I've got many like these I copied from various people over
           | the years.
           | 
           | One I came up and that I use all the time:
           | alias wl='wc -l'
           | 
           | I use it so much I sometimes forget it's not stock.
        
         | bwhaley wrote:
         | Once you start using CTRL+r, you may find that you never reach
         | for up arrow again.
        
           | kuschkufan wrote:
           | And once you want to one-up this look into fzf.
        
             | nidnogg wrote:
             | And once you get tired of fzf and want something better,
             | you reach for https://atuin.sh.
             | 
             | Completely transformed all of my workflows
        
               | seedie wrote:
               | From the atuin.sh website
               | 
               | > Sync your shell history to all of your machines
               | 
               | I think of my shell history as very machine specific. Can
               | you give some insights on how you benefit from history
               | sync? If you use it.
        
               | Cyphus wrote:
               | That feature is entirely optional and disabled by
               | default. Atuin stores your shell history locally in a
               | sqlite db regardless of whether you choose to sync it. I
               | thought fzf was fast, but atuin makes it look slow by
               | comparison.
        
               | foobarian wrote:
               | Same, I find shared history not very useful.
               | 
               | However what I do find useful is eternal history. It's
               | doable with some .bashrc hacks, and slow because it's
               | file based on every command, but:
               | 
               | - never delete history
               | 
               | - associate history with a session token
               | 
               | - set separate tokens in each screen, tmux, whatever
               | session
               | 
               | - sort such that backward search (ctrl-R) hits current
               | session history first, and the rest second
               | 
               | Like half my corporate brain is in a 11M history file at
               | this point, going back years.
               | 
               | What I would love is to integrate this into the shell
               | better so it's using sqlite or similar so it doesn't feel
               | "sluggish." But even now the pain is worth the prize.
        
               | fragmede wrote:
               | You don't have to setup shared history with Atuin if you
               | don't want to and that's what's holding you back.
               | Otherwise it hits the rest of your requirements. Just
               | don't hesitate to change from the default config.
        
               | commandersaki wrote:
               | I just want to give a perspective of someone that uses
               | the 'eternal history' in bash per Eli Bandersky [1] and
               | reluctance to use something like atuin (without/ignoring
               | shared history).
               | 
               | First, as for speed and responsiveness, if there is a
               | degradation, it is imperceptible to me. I wouldn't have a
               | clue that my interactive shell is slowing down because it
               | is logging a command to ~/.persistent_history.
               | 
               | My persistent_history is 4MB and has been migrated from
               | machine to machine as I've upgraded, it's never felt slow
               | to edit with (neo)vim or search with system supplied
               | grep.
               | 
               | Eli's way of doing it also includes the timestamps for
               | all commands, so it's easy to trace back when I had run
               | the command, and duplicates are suppressed. In fact my
               | longest persistent_history goes back to 2019-07-04, so
               | I've been using it for quite some time now.
               | 
               | But the larger point I wanted to make is that I wouldn't
               | feel comfortable switching this, in my opinion, quite
               | efficient setup to displace it with an sqlite database.
               | That would require a special tool to drill through the
               | history and search rendering simple unix utilities
               | useless. As Eli suggested, if your history gets too big,
               | simply rotate the file and carry on. I have the alias
               | phgrep to grep ~/.persistent_history, but I can easily
               | have another alias to grep ~/.persistent_history*.
               | 
               | [1]: https://eli.thegreenplace.net/2013/06/11/keeping-
               | persistent-...
        
               | __MatrixMan__ wrote:
               | 1. work on a project on host_foo in
               | /home/user/src/myproject
               | 
               | 2. clone it on host_bar in /home/user/src/myproject
               | 
               | If you set filter_mode = "directory", you can recall
               | project specific commands from host_foo for use on
               | host_bar even though you're working on different machines
               | and the search space won't be cluttered with project
               | specific commands for other projects.
        
           | pavel_lishin wrote:
           | I'm familiar with ctrl-r, but I still very much like the up-
           | arrow behavior described by that commenter.
        
             | flir wrote:
             | Looking at it from a "law of least surprise" angle, it's
             | exactly how it should behave.
             | 
             | "I typed 'cd di|' and you're giving me 'pwd'??"
        
             | dotancohen wrote:
             | What I love about the default Bash Crtl-C behaviour is that
             | once a command has been located, the bash history is moved
             | to the history of that command, until Enter is pressed.
             | $ a       bash: a: command not found       $ b       bash:
             | b: command not found       $ c       bash: c: command not
             | found       $ d       bash: d: command not found       $
             | <CTRL-R> b <UP>       $ a
             | 
             | That's great if I don't remember which command I was
             | experimenting with, but I do know other commands that I did
             | around that time (usually a file that I edited with VIM).
        
           | BeetleB wrote:
           | There is a difference, I believe. Doesn't Ctrl+r do a
           | substring search instead?
        
             | imglorp wrote:
             | Yes it's different: it will match anywhere in the previous
             | command lines.
        
           | noisy_boy wrote:
           | export EDITOR=vi and then hitting Esc puts you into vi mode;
           | k, j to move up/down through history or pressing / to search
           | etc including using regex is all available.
        
           | soraminazuki wrote:
           | Prefix search is faster for the majority of cases. CTRL-r /
           | FZF is useful for the remaining ones.
        
         | n8henrie wrote:
         | Did this many years ago (but with bash) -- life changing is an
         | apt way of saying it.
        
           | account42 wrote:
           | Here's the Bash commands for this in case anyone is looking
           | for them                 bind '"\e[A"':history-search-
           | backward       bind '"\e[B"':history-search-forward
        
         | moebrowne wrote:
         | This can also be achieved with `.inputrc`:
         | "\e[A": history-search-backward         "\e[B": history-search-
         | forward
        
           | az09mugen wrote:
           | Thank you !
        
         | TacticalCoder wrote:
         | That's a nice one.
         | 
         | One thing I do is configure my keyboard so that
         | "modifier+{ijkl}" mimicks the inverted T arrows key cluster. So
         | there's never a need for me to reach for the arrow keys. And
         | {ijk} makes more sense than vi's {hjkl} and is faster/more
         | logical/less key fingers travel. The nice thing is: as I do
         | this at the keyboard level, this works in every single map.
         | "modifier" in my case is "an easily reachable key in a natural
         | hand position on which my left thumb is always resting" but
         | YMMV.
         | 
         | I set that up years ago and it works in every app: it's
         | gorgeous. Heck, I'm using it while editing this very message
         | for example.
         | 
         | And of course it composes with SHIFT too: it's basically arrow
         | keys, except at the fingers' natural positions.
        
         | BeetleB wrote:
         | Heh. I've done this since forever, but I use PgUp and PgDn so I
         | can retain the original meaning of the up arrow key.
        
           | dsp_person wrote:
           | When I was on ubuntu it was easy to uncomment a couple lines
           | in /etc/inputrc for this
        
         | hebelehubele wrote:
         | This is the default `fish` shell behavior. Type anything,
         | up/down keys to iterate through full commands that containing
         | the term; alt + up/down to iterate through args containing the
         | term.
        
           | naikrovek wrote:
           | Fish is underrated
        
         | sureglymop wrote:
         | I agree it's a game changer! For bash to do the same I put this
         | in my .inputrc:                   ## arrow up
         | "\e[A":history-search-backward         ## arrow down
         | "\e[B":history-search-forward
        
         | Fishkins wrote:
         | I do something similar. I leave up and down arrows alone, but
         | have ctrl+p and ctrl+n behave as you describe.
        
         | naikrovek wrote:
         | Atuin is better than anything I've used in a shell.
        
       | ruptwelve wrote:
       | Maybe not a shell trick per-se but I have been a very big fan of
       | zoxide. It can jump around your common directories. If you have a
       | ~/workspace/projects and you are anywhere and type `cd projects`
       | it will take you to that directory. I never realized how much I
       | got hooked onto it, until I used a system without it.
        
         | llarsson wrote:
         | Built in functionality that may offer something similar:
         | 
         | https://linuxhandbook.com/cdpath/
        
       | TheServitor wrote:
       | great list but really overboard on the AI generated persona
        
       | void-star wrote:
       | set -o vi
       | 
       | <esc> puts you into vi mode at the cli prompt with all the
       | semantics of the editor.
       | 
       | These carpal tunnel riddled hands can't be bothered to reach for
       | ctrl or alt let alone arrow keys.
        
         | cess11 wrote:
         | If you aren't aware already, you can put 'setxkbmap -option
         | ctrl:swapcaps' in one of your startup config files, like
         | .bashrc or somesuch. That flips left CTRL and CAPS LOCK.
        
       | coopykins wrote:
       | My favourite QoL improvement to any shell I use is to improve the
       | history function(Ctlr+R)I personally like
       | https://github.com/cantino/mcfly
        
       | Walf wrote:
       | The utility of $_ is often voided by tab-completion in the
       | subsequent command, at least in bash. You won't know what it
       | contains, which makes it dangerous, unless you first check it in
       | a way that also carries it forwards:
       | 
       | printf %s\\\n "$_"
        
       | fp64 wrote:
       | Here's my favorite tip: If you use bash, you can write bash on
       | your prompt (duh). But this is one of the biggest reasons I stick
       | with bash everywhere, as I am quite comfortable and experienced
       | in bash and sometimes it's just easier to write things like `for
       | i in *.mp3; do ffmpeg -i $i ...` etc. If it's re-usable, I write
       | it to a bash script later.
        
         | integralid wrote:
         | That's vaccously true as you said isn't it? I write fish on my
         | shell and then I can save it as a fish script. Worth noting
         | that bash is much more portable and available by default, but
         | if I'm going for portability I go straight to /bin/sh
        
           | fp64 wrote:
           | Fair point, but for scripting I don't feel fish (or zsh)
           | offer an advantage big enough to bother learning that
           | language with their rather narrow scope. But bash it's good
           | to anyways know, you don't really get around it either.
           | Larger/more complex scripts I write in other languages
           | (depending on domain I and other requirements I guess). It's
           | also not that I daily write those scripts on my shell, so I
           | also think that even if I learned fish or zsh, I would have
           | to look up things again every time I need to write something
           | again.
        
       | martinflack wrote:
       | I use `!!` quite a bit to repeat the output of the prior command
       | as an argument.                   # it's in my PATH but can't
       | remember where         which myscript         vi `!!`
        
       | kleiba wrote:
       | Just recently, I came up with this in my .bashrc, basically a
       | "deep cd" command:                   dcd() {             # If no
       | argument is given, do nothing             [ -z "$1" ] && return
       | # Find the first matching directory under the current directory
       | local dir             dir=$(find . -type d -path "*$1*" -print
       | -quit 2>/dev/null)                  # If a directory was found,
       | cd into it             [ -n "$dir" ] && cd "$dir"         }
       | 
       | I thought this would be way too slow for actual use, but I've
       | come to love it.
        
         | cipritom wrote:
         | you should look into autojump which has `jc` (jump child), or
         | other similar flavours of "smart cd" (z, fzf, etc)
        
           | kleiba wrote:
           | Thanks, but I like that this is just a small, simple bash
           | function without the need to install 3rd-party software.
        
       | SoftTalker wrote:
       | I knew most of these but the $_ variable and "ESC + ." to
       | reference or insert the last argument of the previous command. I
       | can see getting some use out of that, so thanks for posting.
        
         | t312227 wrote:
         | or - as an alternative to <esc> + ".":
         | 
         | for the last argument
         | 
         | * <alt> + "."
         | 
         | if you want the -<n>th argument:
         | 
         | * <alt> + "_" # n times :=)
         | 
         | * <alt> + "."
         | 
         | cheers a..z
        
       | arttaboi wrote:
       | "cd -" is a lifesaver. Thank you so much for this.
        
       | gchamonlive wrote:
       | For me the ultimate trick is to open the current prompt in vim
       | with F2 (Ctrl+X ctrl+E seems to work too):                 # Use
       | F2 to edit the current command line:       autoload -U edit-
       | command-line       zle -N edit-command-line       bindkey '^[OQ'
       | edit-command-line  # f2 is ^[OQ; to double check, run `xargs` and
       | then press f2
        
         | tzot wrote:
         | > # f2 is ^[OQ; to double check, run `xargs` and then press f2
         | 
         | I remember using `cat -v` before learning that `xargs`
         | exists... or maybe before `xargs` _actually_ existed on systems
         | I used :)
        
       | chinadata wrote:
       | only the people do not use pageup and pagedown is who really know
       | how to use shell
        
       | olejorgenb wrote:
       | Do yourself a favor and upgrade your history search with fzf
       | shell integration (or similar):
       | https://youtu.be/u-qLj4YBry0?t=223 /
       | https://junegunn.github.io/fzf/shell-integration/
        
       | scuff3d wrote:
       | Great write up, had to bookmark so I can go through it more later
       | there so much good stuff in there.
       | 
       | For the CTRL + R tip, you can make it even better if you install
       | fzf. Massively improves searching through history. It's worth the
       | install just for that one feature.
       | 
       | Best thing I ever did as a dev was start spending more time in
       | the terminal. Getting familiar with the tools and how they
       | interact makes life so much easier.
        
       | rdevilla wrote:
       | set -o vi
        
       | thibran wrote:
       | Its almost ironical that we still use the Terminal - and many use
       | it like in the eighties using Bash - and seem to have forgotten
       | that we should invent a better terminal & shell than doing all
       | the workarounds to handle the quirks of the current systems.
        
         | mmh0000 wrote:
         | Make a better system, and we'll consider using it.
         | 
         | A Terminal + Bash/ZSH is soooo sticky because they are VERY
         | good at what they do once you learn the basics and quirks. And
         | now with LLMs, CLIs are even better because LLMs talk in text
         | and CLIs talk in text.
         | 
         | Microsoft tried with PowerShell to design a better system; it
         | "technically" is better, but not "better enough" to justify the
         | cost of switching (on Linux). The same is true of nushell; it
         | is "better", but not better enough to justify switching for
         | most people.
         | 
         | I believe we're at "peak input method" until someone invents
         | Brain<->Computer interfaces.
        
           | thibran wrote:
           | I use the Terminal all the time and write my own CLI tools,
           | but I'm feeling more and more the limits of the current
           | system. With the years I have used almost all available
           | shells (EShell was even my default for some time). Right now
           | my favorite shell is Nushell, but still, it feels dated
           | compare to what is possible on modern computers.
           | 
           | > Make a better system, and we'll consider using it. It's on
           | my TODO list, but it will break with all conventions and
           | tools (no TTY). My idea is to bring the chain-things-together
           | idea to the 21st century using a keyboard first GUI.
        
       | MattGrommes wrote:
       | If only somebody had a lifehack for making me remember all these
       | awesome commands.
       | 
       | If I do something the slow way it's usually because I don't do
       | the operation enough to burn it into my memory, or I got burned
       | by accidentally hitting something close but incorrect once and
       | closed the tab or something.
        
         | w-ll wrote:
         | post-it note until you dont need it anymore
        
         | shigawire wrote:
         | I hate to be the AI guy, but a coach that lived in my terminal
         | and corrected me when I do it the slow way would actually help.
        
         | stevthegouws wrote:
         | I find spaced repetition Anki flash cards surpisingly effective
         | for this kind of thing.
         | 
         | You'd think remembering tonnes of shortcuts and commands and
         | flags would be alot of effort but it's surprisingly low effort
         | when using cloze deletions and phrased like:
         | 
         | - "... is to delete the last word" - "Ctrl w is to ..."
         | 
         | If you're not familiar with spaced repetition it's worth
         | checking out, especially if you have a holey memory like mine.
         | 
         | https://ncase.me/remember/
        
       | stormed wrote:
       | You'll look like the coolest person in the office running `sudo
       | !!`. Another personal favorite of mine is using the --now flag
       | for systemctl to enable & start a service in one command (i.e
       | `systemctl enable --now nginx`)
        
       | tzot wrote:
       | On scripts that might handle filenames with spaces, I include:
       | IFS='   ''         '
       | 
       | Hint: the spaces between the first two apostrophes are actually
       | one <Tab>.
       | 
       | This does not affect the already written script (you don't need
       | to press Tab instead of space to separate commands and arguments
       | in the script itself), but by making <Tab> and <LF> be the
       | "internal field separators" will allow globbing with less quoting
       | worries while still allowing for `files=$(ls)` constructs.
       | 
       | Example:                   IFS='   ''         '         echo
       | hello >/tmp/"some_unique_prefix in tmp"         cat
       | /tmp/some_unique_prefix*         fn="My CV.txt"         echo "I'm
       | alive" >/tmp/$fn         cat /tmp/$fn
       | 
       | Of course this will still fail if there happens to be a filename
       | with <Tab> in it.
        
       | alkh wrote:
       | This snippet for zsh still has some rough edges but works for the
       | majority of cases. Automatically extends any global alias when
       | space is pressed in zsh. For ex. I have `alias -G G='rg -s'`, so
       | if I type `command | G` it will autoexpand it to `command | rg
       | -s` and so on.                 globalias() {         local raw
       | word         # raw last blank-separated token, exactly as typed
       | raw=${LBUFFER##\* }         # shell-parsed last word
       | word=${${(z)LBUFFER}[-1]}         # if user typed \alias, don't
       | expand         if [[ $raw == \\* ]]; then             zle self-
       | insert             return         fi         if alias --
       | ${(q)word} &>/dev/null; then             zle _expand_alias
       | zle expand-word         fi         zle self-insert
       | 
       | }
       | 
       | zle -N globalias bindkey ' ' globalias
        
       | nickjj wrote:
       | CTRL+L isn't the same as clear btw, it really maps back to `clear
       | -x`.
       | 
       | CTRL+L clears the visible output but you can still scroll up in
       | your buffer to see the rest, clear will clear that scroll up
       | buffer too.
       | 
       | I've written about and demo'd this in
       | https://nickjanetakis.com/blog/clear-vs-ctrl-l-in-your-shell.
        
       ___________________________________________________________________
       (page generated 2026-03-26 23:01 UTC)