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