44

I have a lot of commands I routinely need to execute, often with the slightest variation.

Right now I'm storing them all in .bash_history and use CTRL-R to access them, but I wonder if there's a better way. What I'm looking for:

  • Easy to add a new command
  • Easy to search and re-execute a wanted command
  • Avoid unwanted commands in suggestions

Unfortunately, bash_history is not so strong on the third demand: if I do a few cd and ls, it fills the history file quickly. I have recently learned about HIST_SIZE and that you can configure the history to avoid duplicates or certain commands, but before configuring all that, I wanted to make sure it is the best way.

don_crissti
  • 82,805
Konerak
  • 1,451

13 Answers13

72

Another tip: I sometimes use comments to bookmark/tag a command:

my_command #bookmark

then:

[ctrl-r]#bookmark
Chris J
  • 964
22

I find very useful the following readline commands

history-search-backward,
history-search-forward

(be aware they are different from the usual reverse-search-history, forward-search-history, tied to Ctrl-R, Ctrl-S).

I have these commands associated to Ctrl-Up and Ctrl-Down putting the following lines into ~/.inputrc:

"\e[1;5A": history-search-backward
"\e[1;5B": history-search-forward

How they work: write few chars of the beginning of the command, press Ctrl-Up and the next older command starting with that prefix will be shown, press again to see the next, and so on. When you are satisfied, after possibly modifying the command, press Enter to execute.

enzotib
  • 51,661
  • 1
    +1 for this, I do the same although I just have them bound to the Up Arrow and Down Arrow keys (no CTRL modifier), which works for me. If you want to do likewise the lines you need are "\e[B": history-search-forward and "\e[A": history-search-backward – Simon Whitaker Dec 08 '11 at 03:21
  • Also consider growing HISTFILESIZE and/or HISTSIZE (zsh supports only HISTSIZE, bash supports both) to ensure your buffer is sufficiently large. The SO question bash HISTSIZE vs. HISTFILESIZE? can illuminate further. – Adam Katz Jan 15 '15 at 17:47
7

Use 'alias'

alias is a great tool for this.

  • You can easily declare one on the command line to be used during the current shell session.
  • If you'll use it in the future, you can add it to your shell config.

When you use an alias, it's exactly as if you'd typed it, so it's quite flexible. For instance, you can use it with pipes:

alias findfoo="grep 'foo'"
echo 'foo1 \n foo2 \n bar1 \n bar2 \n foo3' | findfoo # Does your custom grep

You should be able to do "slight variations" by passing any flags you didn't already specify.

echo 'foo1 \n foo2 \n bar1 \n bar2 \n foo3' | findfoo -v # finds non-matches
Nathan Long
  • 1,623
7

Although of very limited scope, I'd like to point out these two expansion placeholders:

!! 

is a placeholder expansion for the last command. Useful if you forgot to put sudo before the command.

!$ 

repeats the last parameter. Useful if you want to repeat a different command with a/very/long/path/name/you/do/not/want/to/type/again

chiborg
  • 231
5

I'm maintaining a copy of .bash_history in Git. To simplify this, I've set

# don't put duplicate lines in the history
# don't save commands which start with a space
HISTCONTROL=ignoredups:erasedups:ignorespace

# append to the history file, don't overwrite it
shopt -s histappend

in .bashrc, and the following commands (modified for general use) in a cleanup script

# Ensure a single space at the end of each line to easier add more parameters
sed -i -e 's/ *$/ /' "~/.bash_history"

sort --unique --output="~/.bash_history" "~/.bash_history"

which I run before adding lines in git gui. Since the history file is modified with every command, I've also got a special command to update that specific repository:

git stash && git pull && git stash pop
l0b0
  • 51,350
  • +1 primarily for mentioning HISTCONTROL=ignorespace, which is important for not cluttering up history, sometimes. – quodlibetor Apr 09 '12 at 19:38
5

I create minimal shell scripts for my frequent commands and give them short names. They are all stored in the same place, which is added to PATH.

That way I have shortcut access to very complex commands, and unlike with alias I can turn the changeable parts of my task into command line arguments of my shortcut.

  • 3
    If you just want to pass arguments, consider defining functions instead. If you need full scripts, this is a good solution :) – Konerak Dec 07 '11 at 15:56
  • @Konerak I'll have to try that. I usually just make a script, but defining functions would be a lot cleaner, I bet. – ixtmixilix Dec 13 '11 at 11:49
3

Among all the other answers here involving history.

I set

HISTFILESIZE=2024
HISTSIZE=1024

in ~/.bash_profile

In addition to the other comments re: history

Another useful feature...

Beginning a history recall with

!first few letters<ESC>Ctrl-E

will recall the last command that began with first few letters

eg:

!find<ESC>Ctrl-E

You didn't mention whether or not you're using a GUI, or command line only. If you're using a GUI, you can use one of the persistent clipboard managers to copy/paste commonly used commands, userids, passwords, urls, etc.

bsd
  • 11,036
2

Looking for the same thing. I'm only on our linux servers every couple of weeks and I forget some of the commands.

For those still finding this question in search results, I used Marker to bookmark my favorite commands (I only have a half dozen or so).

Seems to be a good fit for OP requirements:

  • Easy to add a new command
  • Easy to search and re-execute a wanted command
  • Avoid unwanted commands in suggestions

This solution even solves the 3rd requirement. No worries about the duplicates in a bash history.

The developer added a bunch of default commands that I did not need. I removed them by deleting the text files in ~/.marker/tldr. You can always restore these from GitHub if you change your mind.

Marker example

Rich C
  • 121
0

Learning to use Ctrl-R and Ctrl-S allows to easily search for the commands you are looking for in the history, and you already found the HISTCONTROL environment variable to ignore duplicates and change the site of bash history file.

I usually do many Ctrl-R followed by Ctrl-E and changing some parameters, if I skipped a found command by hitting Ctrl-R one too many times, Ctrl-S to the rescue.

0

I always prefer to store last used commands and their output.

script filename
0

Additional to using Cntl-R to look back in the .bash_history, I also have a README file in the ~/develop directory where I put long commands like for git / svn, so I can come back to them later when I need to. Similarly, I am planning to have an ~/install/README file to put all the common package names that I usually install after installing a new version of Linux/Ubuntu. So the idea is to have a README file inside every directory, e.g. Video, Audio, ... and put in them the common commands / tips, that you might need to know in a later time.

Kevin
  • 40,767
Amr
  • 1
0

In addition to the good answers above, if you happen to be using a gui based on kde or gnome, then AutoKey can be amazingly helpful.

https://code.google.com/p/autokey/

It allows you to create phrases that are triggered by typing in a few characters or pressing a hotkey. These phrases are then substituted for or added to your input.

It also supports scripts written in python that you can make do almost anything if you know python. I don't know python yet, but I'm already getting some very basic scripts to do neat things.

Everything appears to be coming from your keyboard, so it works with any application that accepts keyboard input - and with your desktop, itself.

It has a lot of options controlling how and where these things get activated, so you can have some that only work in your console and others that only work in another window. You can also set phrases to run as soon as you type the string that triggers them or wait until you give them the OK.

Joe
  • 1,368
0

Like others have said alias is your friend. For a little more complicated things (when you need arguments somewhere between instruction) I use functions in my .zshrc, like:

function ff() { find . -iname "*$**" }

that works like locate (I use it when for some reason db is not available). Or

function chuck() { ps aux | grep $1 | tr -s '\t' ' ' | cut -f2 -d' ' | xargs kill $2 }

for a substitute of killall.

rkj
  • 101