Bash – Ctrl-R style interactive search in custom file

bashcommand history

I want to be able to search a custom text file similar to the interactive history search in bash.

Once the wanted entry is found, executes the line.

Bonus Points:
have each record contain two fields – the search target, and the command that will be executed

What I'm trying to accomplish with this is to allow quick auto completion of server names from a server list.

Best Answer

You can load a custom file into your Bash history itself using the history command. history -r will read the file you name in as your command history, or the file named in HISTFILE if you don't name one:

history -r ~/custom

After this you can use any of the ordinary actions that access the history with the data from your custom file, including Ctrl-R, ! history expansion, and so forth.

If you only want to have this enabled temporarily, you can save your current history, read the custom file, and then read the ordinary file back at the end:

$ history -w # Or -a if you prefer
$ history -r ~/custom
...
$ history -cr

history -cr will clear the history in memory and read it in fresh from the standard history file $HISTFILE. You can also make aliases to shorten this process.

Alternatively, you can add computed values to the history using history -s. The following is equivalent to just reading the file:

while read command
do
    history -s "$command"
done < ~/custom

You can add as many arbitrary history entries as you want in this way, computed from whatever data you have available (e.g, read a list of server names and ports and use history -s "ssh -p $port $servername"). This works well in a function. The same options to write, clear, and restore history apply here too.

As a final option, if you set HISTFILE in the environment when starting bash then it will honour that file as your history. You can launch a new shell from a script with HISTFILE set appropriately to let the user pick a command: HISTFILE=~/custom bash. With careful construction you could make that shell terminate immediately after running the selected command.


Moving outside Bash itself, rlwrap is a tool to wrap up any other command-line tool in Readline. rlwrap -H ~/custom cmd... will run a command with the given file of history. You can build that program to do exactly what you want, including selecting only the server name with user input and building the command up afterwards.