16

For some projects I often type in a couple commands, like for example:

cd an/extremely/long/path/in/which/I/have/some/kinda/project

and

./runmyproject --with some --command line --options set

Seeing that I'm pretty lazy I try to avoid typing those commands in full again and again. So I can of course use the up-key a lot to find back those commands, but often, I also have so many commands in between, that searching for it takes even more time than just typing it.

I now wonder if there is some kind of utility that can suggest a full command which I use a lot, when I haven't typed all of it yet. So that I can for example type 'cd an/' and that it already suggests the rest of the path because I've used it so much the past month.

I did find something called Bash Smart Complete. But that is a little "dumb" in that it doesn't look at the commands I used before. I just also found this SO answer, which suggests putting the commands I use a lot in a file. That however, is not responsive enough in that I would need to create a new file for it every time I start new projects or change folders or program arguments.

Does anybody know any other utility or other way to achieve this? Or, would anybody know how I could alter the Bash Smart Complete so that it can look at the commands I used in say the past month and complete the command which fits and has been used the most in the past month?

[EDIT] Below are some really great answers. I haven marked any as a definite answer yet. Not because I do not like the answers, I do, but because none of them is an absolute winner. I think the Finalterm is a great project. Unfortunately it is still rather rough around the edges. For example; it doesn't support copy-paste yet. I would keep on eye on that project though, because when it will mature I think it'll be a great terminal app. As for the other answers; they either suggested creating an alias, which is not what I want to do because it creates extra work instead of taking work away, or using Ctrl+R, which is a brilliant (I didn't know about it!). A couple of people suggested using Ctrl+R, so I can't really highlight one answer over the other.

So for now I am definitely using Ctrl+R, and in the future I might use Finalterm.

Thanks for all the great answers guys!

3
  • 2
    You should really try zsh. It offers everything you're asking for and lot more. Moving from bash to zsh Jun 16, 2013 at 0:51
  • According to BASH man page, the function is also present in BASH as "dynamic-complete-history". By default it is bound to Alt+Tab making it useless, but one can change the binding with "bind".
    – Boris Bukh
    Jun 16, 2013 at 11:22
  • 1
    @BasharatSial what specifically does zsh do to help with this?
    – poolie
    Jun 17, 2013 at 8:25

7 Answers 7

17

If the commands are often used, they are recorded in the command history bash tracks in .bash_history.

Now the trick: You can reverse search this history to re-execute commands by pressing CTRL-r.

In inverse history search mode, bash shows, live, as you type, the most recent command in the history that start with your given input. Then press enter to accept and execute the proposed command. Keep pressing CTRL-R to cycle to older commands with the same prefix.

This is builtin in bash, no need for customizing scripts or install software :) It is one of the most useful features of bash, imho.

1
  • 3
    Use [CTRL-g] to escape from the history search mode, if not executing a command (such as if you didn't find the one you needed).
    – MountainX
    Jun 19, 2013 at 4:05
8

Paste (Ctrl-Shift-V) the following into a terminal screen:

echo '"\e[A": history-search-backward' > ~/.inputrc
echo '"\e[B": history-search-forward' >> ~/.inputrc
echo 'set show-all-if-ambiguous on' >> ~/.inputrc
echo 'set completion-ignore-case on' >> ~/.inputrc

Exit (Ctrl-D) the terminal screen, then open Terminal again.

Now you can just type the first couple of characters, then press Up or Down to scroll through the filtered list

1
  • 3
    This is the simplest answer that gets the job done!
    – cxrodgers
    Jun 19, 2013 at 2:37
8

Final Term

There is this very promising Terminal App Called Final Term. Among its many features, it also has a history of remebering commands, so that you can then select it. Here are some more features:

Final Term

You can read more about it in this article.

Here is the the website from the creators. http://finalterm.org/

To Install it

sudo add-apt-repository ppa:versable/finalterm-daily
sudo apt-get update
sudo apt-get install finalterm

Warning

I have said that it is promising. The only issue is that it is at version 0.1. So some things like vim and nano don't work well yet. I have also noticed that it does not yet support Drag-and-Drop, and copy and paste. But it does have the feature you request. As the software matures, it will become one of the best terminals for the desktop.

Screenshot

Here is the function in action:

 function in action

Hope this helps.

*I am on Saucy, so that is why I have a Salamander background :)

2
  • Thanks for the tip! I checked out finalterm and it does look good. Unfortunately it doesn't seem to support copy-paste yet. I tried Ctrl+V, Ctrl+Shift+V and right-clicking, but none of those seem to work. So I'll keep this one in mind for the future!
    – kramer65
    Jun 17, 2013 at 6:33
  • That is the biggest drawback that I saw. However, the project is young, and so I have hope that that will be added soon. I can see a terminal app with out copy-paste support.
    – Max Tither
    Jun 17, 2013 at 18:22
7

Use an alias for your whole command, or add the directory into your $PATH. Additionally, you don't have to change directories to where your executable (or script, or whatever) is to run it, so it's fairly simple. Both methods require you to restart the terminal you're using before the changes take effect.

Here's how to create a bash alias for your example (add the following line to your ~/.bashrc file):

alias runmyproject='an/extremely/long/path/in/which/I/have/some/kinda/project/runmyproject --with some --command line --options set'

This way, all you need to do is input runmyproject into terminal wherever you are, without having to specify options/arguments.

Alternatively, you could add your project path into your $PATH environment variable. To do so, add the following lines into your ~/.bashrc file:

PATH=an/extremely/long/path/in/which/I/have/some/kinda/project:$PATH
export PATH

In this case you'll still need to specify your options/arguments for your executable when running it.

2
  • 1
    The thing is that I would like the terminal to be responsive to my use. With this I have to change the alias every time I start working on new projects or when I change the directory structure of my project. The main part of my question is that I want it to learn from what I use, instead of me telling it what to do.
    – kramer65
    Jun 17, 2013 at 6:34
  • Ah I see. Then the currently top-rated answer should do the trick. Or at least closely.
    – oaskamay
    Jun 17, 2013 at 20:58
4

When I find myself frequently having to change to a directory like this:

cd an/extremely/long/path/in/which/I/have/some/kinda/project

I would just do this once:

ln -s an/extremely/long/path/in/which/I/have/some/kinda/project ~/project

And from then on, use:

cd ~/pr[tab]

When it comes to:

./runmyproject --with some --command line --options set

I would use the bash history search. At the command prompt just press Ctrl-R and type 'runmy'. Voila, the whole command with all the options as it was last entered is right there to be re-entered. If I didn't like the options I used the last time and wanted to look at the earlier commands, I'd keep pressing Ctrl-R to cycle through all the previous commands that contained "runmy".

The Ctrl-R history search could help with the 'cd' command too, if you don't like the symlink idea. [Ctrl-R]/proj is really likely to bring back the last command you used to cd to that directory.

Rather than adding an alias or switching to a special shell, I always prefer to learn to use the bash features designed to help with this sort of thing. That way I can use the same features on remote machines or if I have to sit down at a colleague's terminal.

1
  • Thanks for your suggestion. The thing is that I don't want to set another thing which I have take care of when for example the project folder changes or I start a new project. The thing is that I would like the terminal to be responsive to my use. The main part of my question is that I want it to learn from what I use, instead of me telling it what to do. I really like the Ctrl-R function though. Thanks for that one!
    – kramer65
    Jun 17, 2013 at 6:38
4

hit control + r on your keyboard - it will put you in reverse history mode and you can type the part you know and the whole command will show

There are other ways listed here

http://www.talug.org/events/20030709/cmdline_history.html

I tend to use control R the most though

2

Try this... This works for all commands in your history file... is the same thing as Ctrl+R, but I think that is more intuitive :)

  1. edit /etc/inputrc

    sudo vim /etc/inputrc
    
  2. uncomment or add this two line

    "\e[5~": history-search-backward
    
    "\e[6~": history-search-forward
    
  3. logout/login


then try to write some command listed in history...

like...

ls -lah

write

ls

and press

Page Up or Page Dn to navigate trough your history file in search of commands that starts with "ls"

If you did everything right it should auto-complete your command...

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .