
The most useful thing in bash - bitsweet
https://coderwall.com/p/oqtj8w
======
aw3c2
Since this is ugly clickbait, here is the "content" of the linked site:

> Create ~/.inputrc and fill it with this:
    
    
        "\e[A": history-search-backward
    
        "\e[B": history-search-forward
    
        set show-all-if-ambiguous on
    
        set completion-ignore-case on
    
    

> This allows you to search through your history using the up and down arrows
> … i.e. type "cd /" and press the up arrow and you'll search through
> everything in your history that starts with "cd /".

~~~
saym
clickbait? Are you suggesting that this would've been better as a Show HN
post?

I have no problem viewing the site of someone trying to show me something
useful.

~~~
fyi80
The title could be factual instead of sensational.

~~~
pvnick
I don't know, when I read the title the first thing my mind jumped to was
CTRL-r command searching. I was thrilled to see something similar but better.

~~~
rrrene
For highly subjective definitions of "better", that is.

------
babs474
This is a killer feature of emacs and M-x shell for me.

Now my command history is searchable, just like any other file or buffer I
have open.

I use the same idea for any repl, R,python,ruby,node,clojure. Bash is just
another repl.

The major advantage of the emacs buffer method is that a lot of tasks I do on
the computer span many commands. I can search for one command I remember
executing 3 months ago, and then review the series of steps I took before and
after, along with the output.

Typically finding a single command I've executed before doesn't help a whole
lot. I need context.

~~~
jaredandrews
M-x shell is one of the first things I just show people when I introduce them
to Emacs. I had a databases class a few years ago where the CLI program we
used to interact with the database was a basically an input loop where you
entered commands. It had absolutely no concept of history though so if you
messed up a query you had to retype it or use the clunky copy and paste
feature of whatever terminal emulator you were using. Emacs changed everything
though be cause I could just kill my last command and paste it into the new
prompt. I have since done this with many other commands and I love it.

~~~
callmecosmas
I'm an emacs lover myself, but for that use-case it seems like all you need is
rlwrap: <http://utopia.knoware.nl/~hlub/rlwrap/#rlwrap>

------
drcube
C-r isn't much harder than up/down arrows (or C-p/C-n). Why is this such a big
deal?

~~~
gbog
With C-r you need to first type C-r, then type your search key. With the OP's
inputrc nice hack, you first type the begining of your command, and then up.
To me it is very different.

~~~
buddhistpirate
With Ctrl-R it is the same. If you start typing a command, then type Ctrl-R it
will use that as the first part of your search.

~~~
yannk
You sure? Not in the bash versions (3 & 4) I'm using... In anycase, I'll stick
to C-R since I know it works universally. And I depend on C-R quite a bit.

------
yutyut
Ctrl+R lets you search old commands in a similar way. I would say it's more
intuitive, too.

~~~
geoka9
Not to mention that it doesn't require you to take you right hand off the home
row.

~~~
3JPLW
Bind:

    
    
        Control-p: history-search-backward
        Control-n: history-search-forward

~~~
kleiba
Then how do you go to the previous command without leaving the home row?

~~~
3JPLW
Still works if you haven't typed anything yet. If you have (and don't want it
as your search):

    
    
        C-a C-k C-p

------
svachalek
One history trick I use a lot that most people don't seem to know about is the
!$ variable, which refers to the last argument of the previous command. It's
basically a bash pronoun. !! is the entire previous command which is
occasionally useful with find:

find . -name foo

vi $(!!)

~~~
dllthomas
$_ is a variable for the same thing. The only difference winds up being the
effect on the current line's result in your history: !$ is replaced while $_
stays $_ and so its meaning will change if you run the same command later,
which can be what you want or not, depending.

~~~
scott_karana
You're right in this specific case, but there are other useful ! arguments, so
it's worth learning both.

It's the "Event Designators" in the bash manpage for those who are interested.

~~~
dllthomas
Oh, I didn't mean "You should use $_ instead", just "$_ is also useful."

As I tried to indicate, you should ideally use whichever will make more sense
in your history later. If the command you're typing should always be applied
to that file, which happened to be the last argument of the previous command
this time, then use !$; if the command you're typing should always be applied
to the last argument of the previous command, and it just happened to be that
file this time, use $_.

------
curtis
I've always found interactive history UI to be difficult to work with beyond
the most trivial cases. Instead, I'd always find myself typing "history | grep
..." over and over again. Eventually I wrote an improved history command with
built-in filtering: <http://curtisb.posthaven.com/a-better-history-command>

~~~
ajross
It's funny how personal workflows can be. I do the history|grep thing too, but
never felt the need to automate it further. It's a relatively rare thing
(maybe once a day), used when I know I did something specific in the past but
forget a detail or two.

Instead, I generally drop little shell scripts around my work area for
specific tasks. Working on iterating a build/install to chase a specific bug?
Stuff it into a little script. Writing a find command to munge a bunch of
files with xargs or -exec or whatnot and realize I'm into the third line or
editting? Stop and echo it into a file, then finish it in emacs.

The idea of doing all that junk and then relying on the bash history file
(instead of, y'know, the actual filesystem) to store it for me seems weird.

~~~
dllthomas
I use screens and session variables to manage context, so scripts don't need
to be "around my work area" but rather in the appropriate
~/.context/$SESSION/bin directory (or ~/bin if sufficiently general).

~~~
ajross
Again, personal taste leads me to say "yuck" to this one. You don't think that
the appropriate spot to do an ad-hoc build integration is the source
directory? You'd rather put it somewhere that has to do with the window into
which you're typing (which for obvious reasons won't survive a reboot or copy)
and not a place that corresponds to what you're actually doing?

~~~
dllthomas
Ah, if something's particularly specific to a directory subtree, rather than a
particular context/task, I'll drop it in the tree sometimes, for sure. But my
contexts very much correspond to what I'm actually doing (and my prompt
includes the session), and so ~/.context/$SESSION/bin _is_ "a place that
corresponds to what [I'm] actually doing".

Which is not to take away from your "it comes down to personal preference" by
any means - just trying to make mine a bit clearer.

~~~
akkartik
How do you persist these scripts across sessions?

~~~
dllthomas
I'm not sure just what you mean, but to try to answer: $SESSION contains a
meaningful context name, not a nonce string. Stuff in ~/.contexts/$SESSION
sticks around unless I manually remove it (I also store context specific
history and config files there). If I need to access a script from another
context, I can just give the full path - winds up working a little bit like
namespaces.

------
DavidSJ
One super-useful bash feature is anonymous named pipes, which allows the
equivalent of multiple pipe "arguments" to a single command.

Instead of:

echo a b c > /tmp/foo

echo d e f > /tmp/bar

diff /tmp/foo /tmp/bar

Just do:

diff <(echo a b c) <(echo d e f)

~~~
dhamidi
That feature is actually named "Process Substitution".

"anonymous named pipes" is contradictory, since anonymous means that something
has no name.

~~~
DavidSJ
Yeah, poor wording on my part. They do have a name, but normally you don't
care about it.

------
dbbolton
I use pg up/pg dn for history searching and leave the arrows for simple up and
down lines, like so (in zsh):

    
    
        [[ -n "${key[Up]}" ]] && bindkey "${key[Up]}" up-line-or-history
        [[ -n "${key[Down]}" ]] && bindkey "${key[Down]}" down-line-or-history
        [[ -n "${key[PageUp]}" ]] && bindkey "${key[PageUp]}" history-search-backward
        [[ -n "${key[PageDown]}" ]] && bindkey "${key[PageDown]}" history-search-forward

------
StavrosK
That's why I use fish. Not only does it cycle like that by default, but it
autocompletes entire commands, searches for the substring in the middle of
words, looks better, is faster, etc etc.

~~~
dsl
I am really amazed more people on HN aren't using fish. Everyone should check
it out: <http://ridiculousfish.com/shell/>

~~~
jfb
It's unfortunately on the one hand too beholden to POSIX shell behavior, while
still being too different from mainline Bourne derivatives. I've tried it a
few times, and the cognitive load is too extreme for my 20+ yrs of POSIX
brain-damage to work around.

~~~
sourpoi
I don't use fish for shell scripting, but I'm enjoying it as my primary
environment after making these adjustments..

Status codes and argument lists:

    
    
        $status  # replaces $?
        $argv    # replaces $@
    

Aliases are just functions (configure your startup in
~/.config/fish/config.fish):

    
    
        # alias ls="ls -lrth"
        function lr; ls -lrth $argv; end
    

For-loops are familiar:

    
    
        # for n in one two three; do echo $n; done
        for n in one two three; echo $n; end
    

The lack of '!$' confounded my hard-wired fingers until I settled on Alt-u to
avoid up-arrows (see
/usr/share/fish/functions/fish_default_key_bindings.fish):

    
    
        bind \eu history-token-search-backward  # replaces !$
        bind \ei history-token-search-forward   # bonus fun
    

The remaining price for fish's pseudo-telepathic assistance is the occasional
frustration with applications that rely on the value of a user's default shell
(/etc/passwd).

------
felix
Or there's always "set -o vi" then you can search through your history with
/foo and n to find the next match.

------
mdpye
What does this give you over the default Ctrl-r?

~~~
csmatt
my thoughts exactly

~~~
dima55
Ctrl-R finds commands that contain the string anywhere. The method the OP
posted finds commands that begin with the string. This is an important
difference, and if you give it a try, you'll likely agree the latter is what
you want most of the time.

~~~
mh-
C-r in zsh takes regexp patterns (so you could do *^substr to match begins-
only).. I hadn't noticed this wasn't the behavior in bash with readline.

Anyone know if that can be done in bash/readline?

~~~
mh-
whoops, errant asterisk that I can't edit out. unclosed attempt-to-italicize

------
shmerl
It's not the same as Ctrl+R - it actually doesn't look for a match in the
middle of the string, only from the beginning of it, so while it's better with
going back and forth between the matches, it matches less data to begin with.

------
civilian
Awesome. I wrote another history tool called "list commands"

The idea is that: many commands are location-specific. When you type `lc`, it
will only give you commands that were executed in that directory.

<https://github.com/pconerly/lc-listcommands-bash>

I would love to get some up/down arrow ability for `lc`. Right now I do a lot
of:

$ lc | grep X

------
asb
I also love the history-search-{forward,backward} shortcuts. I took over the
Raspberry Pi SD card image generation process back when we moved to Wheezy for
the 'official' images and put this shortcut in to the default install with the
hopes of leaving it there if no-one complained. Sadly someone did, I caved in,
and it is no more.

------
xbryanx
AutoJump is my co-pilot in these situations:

<https://github.com/joelthelion/autojump>

------
xutopia
Something that gives this snippet much more weight.

export HISTSIZE=10000

Allows you to have a much bigger history.

~~~
sikhnerd
You would also likely want to increase HISTFILESIZE as well. HISTFILESIZE sets
the size of the history file, HISTSIZE is per-session

------
vowelless
My favorite history trick in bash is "cd -".

~~~
jamesjporter
A funny story about "cd -". When I first started learning the command line
during a programming course, they basically told us just enough to get by in
order to complete the assignments. Somehow, "cd -" was mentioned but not "cd
..", so for a long time I used "cd -" as my only method for getting to the
parent directory! (since that was usually where I had just come from). Reading
about everyone discovering "cd -" much later in learning bash is very amusing,
since I have been using it since day one (albeit in a totally incorrect way!)

------
johtso
And if you use ZSH you can go one step further with proper substring search.

<https://github.com/zsh-users/zsh-history-substring-search>

------
tehwalrus
This doesn't work for me on Mac OS X Mountain Lion. I get:

    
    
        -bash: \e[A:: command not found
        -bash: \e[B:: command not found
    

when my shell starts, and it doesn't work.

~~~
davemaya
just use oh-my-zsh <https://github.com/robbyrussell/oh-my-zsh> this feature is
enable by default.

------
sirwitti
Thanks a lot. I never liked Ctrl+R. This is also the way Vim handles
history...

~~~
willismichael
Ctrl+R always seems natural to me, but maybe that's because I'm an emacs user.

------
rdtsc
I disagree.

1) If you work on multiple machines avoid heavy configuration and remapping of
keys. It will frustrate you to no end. "Oh I forgot on this machine it is the
up arrow on the other it is Ctrl+R" etc.

2) Up/Dn Arrows already do a useful thing -- they cycle commands in historical
order. That is also useful in addition to the Ctrl+R history search.

~~~
hobs
I couldnt agree more. I had a knee jerk reaction to say that it would be
someone who works in bash who would say something like this, because
constantly sshing in to various boxes and having to constantly tweak your
various . files is a fucking pain.

But after thinking it over, I definitely know those who are awesome sysadmins,
and require every bit of the setup to match their preferences before they will
deign to work in that system.

~~~
mixmastamyk
Use version control on your dotfiles.

------
mitchty
Umm, .inputrc is readline not bash so technically this can be used in anything
linked to readline?

~~~
Nick_C
Yes, including REPLs that use readline. Those that don't you can use rlwrap.

------
chmike
I get "\e[A" and "\e[B" command not found.

Otherwise it works. But ... ctrl U to clear the line, doesn't clear it
completely. It only clears text from the start of the line to the prompt. What
has been added from the history is left there one the line. I have to first
move to the end of the line then type ctrl U to clear it.

------
skcin7
My bash does this automatically and I do not have a ~/.inputrc file. I'm on
Mac OS X 10.8.2 using the Terminal app (which is a bash command line
interface). I assumed this was a default feature of bash but apparently not.
If somebody can explain to me why I have this feature by default, I would be
grateful.

~~~
lux
Bash will up/down between past commands, but it's unfiltered. This lets you
type the first few characters you know you're looking for to find it faster.

~~~
skcin7
OHHHHHH. I get it now. Thank you for the explanation.

------
pajju
I use fasd: Its the best bash tool out there. Jump, search the previous
history based on frequency of usage. It updates your search with its algorithm
matching the most predicted one.

<https://github.com/clvv/fasd>

worth mentioning, nothing comes close this one.

------
coherentpony
Does someone care to explain the difference between this and <C-r>?

~~~
gknoy
C-r will search what you type afterwards, (e.g., "C-r ssh" will then show me
the previous command that starts with "ssh") whereas this tip seems to be
searching to match what you've already typed. Pretty cool, IMO.

------
alpb
I am using oh-my-zsh and this is already configured for me.

~~~
michaelmior
I've been using oh-my-zsh for around a year now and I never realized this.

------
bherms
When I paste this and then source the file, I get:

-bash: \e[A:: command not found -bash: \e[B:: command not found

edit: thanks for the responses below. Learn something new every day :)

~~~
MostAwesomeDude
inputrc is not to be sourced; it's read by readline when the shell starts. You
need to restart your shell.

~~~
sikhnerd
CTRL-x-r will reload it as well, without having to restart your shell

------
KevinMS
Anybody know how to get this to work with Ctrl-p and ctrl-n? I try not to
touch the arrow keys because they are too small on my new keyboard :(

------
nshankar
Useful. Please share if you have such gems.

------
james2vegas
Or just use vi mode 'set -o vi' in sh, 'set editing-mode vi' in ~/.inputrc for
bash and other readline clients.

------
merraksh
This would not allow me to

1) start typing a command;

2) look at or copy+paste stuff from the previous commands

I usually do my history search through history|grep.

------
Numberwang
Good old doskey

~~~
skarlowicz
I wouldn't be surprised to learn I'm the only living person still using
doskey. Yes, in April 2013, and on W7. I autoload a file with macro
definitions in cmd prompt window, and this works great for programs I want at
my fingertips but don't want to clutter PATH with (or desktop with shortcuts,
or create a .bat/.cmd etc; I do realise there are other ways to do that, but
my solution works good enough since DOS times). The unfortunate thing with
doskey aliases is you cannot use them as pipe recipient, they have to start at
the line start. On the other hand, they can accept parameters.

------
jfb
% exec env zsh

------
rhizome
This tip is default behavior in tcsh.

~~~
alinajaf
And fish.

~~~
yoava
And even our old Windows shell...

------
D9u
I thought that the command history search was default behavior for BASH? (I
use zsh)

------
Syssiphus
Or I could use Ctrl-r.

------
mbetter
I would say the single most useful thing in bash is the ability to type in
commands.

~~~
blablabla123
agree, there is (obviously) some key combination that does the same thing
without changing the usual behaviour of up/down which I prefer a lot

~~~
pavel_lishin
To be fair, if your prompt is empty, up/down behavior doesn't change.

I guess I re-run commands fairly often, so for me the history-search-backward
thing is very useful; when I just need to use the default up/down binding, I
just hit Ctrl-E Ctrl-U (go to end of line, erase everything to beginning of
line) and I'm good to go.

~~~
blablabla123
> To be fair, if your prompt is empty, up/down behavior doesn't change.

Ok, but what if your prompt is empty and you press up once? Will it still
continue to maintain the old behaviour?

~~~
pavel_lishin
Yes.

To expand on this, it searches based on what's on the left side of your
cursor. So if your cursor is all the way on the left side, it acts as it did
before. You lose nothing!

~~~
blablabla123
This is indeed very nice.

