Under Construction

The Options histreedit and histverify

To demonstrate the two bash options histreedit and histverify, let’s assume the following history:

[user01@aixe01 ~]$ history
    1  pwd
    2  ls
    3  date
    4  ls -l long_file_name.txt
    5  who
    6  ls working_copy_of_sample.txt
    7  ls
    8  pwd
[user01@aixe01 ~]$

The content of the two files long_file_name.txt and working_copy_of_sample.txt shall be concatenated and saved in the file combined.txt. The command for this would be:

cat long_file_name.txt working_copy_of_sampel.txt >combined.txt

That’s quite a bit of typing! If you look at the history, you can see that both files have already been used as arguments in commands. The file name long_file_name.txt is obtained via the history expansion “!?long?:2“, the file name working_copy_of_sample.txt via the history expansion “!?work?:1“. With the use of the history expansions you could use the following command:

cat !?long?:2 !?work?:1 >combined.txt

This is quite a bit shorter than the command written out above.

Note: Of course, you can do this even shorter with “!4:2” and “!6:1“, but here we are not concerned about the shortest possibility.

But of course we can also make mistakes when using the history expansion. We show this by omitting the letter “o” (accidentally) from “work” in the last-mentioned command:

[user01@aixe01 ~]$ cat !?long?:2 !?wrk?:1 >combined.txt
-bash: !?wrk?: event not found
[user01@aixe01 ~]$

The bash gives a corresponding error message and of course we see our error immediately (missing “o“). Unfortunately, you can no longer access the command and correct the error. The command line must be re-entered. The bash option histreedit (when using readline) can help here. If the histreedit option is set and a history expansion fails (as in the example above), then the entered line is displayed again and can be corrected:

[user01@aixe01 ~]$ shopt -s histreedit
[user01@aixe01 ~]$ cat !?long?:2 !?wrk?:1 >combined.txt
-bash: !?wrk?: event not found
[user01@aixe01 ~]$ cat !?long?:2 !?wrk?:1 >combined.txt

Now the missing letter can be easily inserted and the command restarted:

[user01@aixe01 ~]$ cat !?long?:2 !?work?:1 >combined.txt
cat long_file_name.txt working_copy_of_sample.txt >combined.txt
[user01@aixe01 ~]$

Next, let’s imagine that the working_copy_of_sample.txt file is no longer needed and shall be deleted. Via the history expansion “!?work?:2” (or shorter “!:2“) we have access to the file name and can specify it as an argument with rm:

rm !?work?:2

Let’s imagine that we miscounted the argument number and used “1” instead of “2“:

[user01@aixe01 ~]$ rm !?work?:1
rm long_file_name.txt
[user01@aixe01 ~]$

The wrong file was deleted! The command is still displayed after the history expansion, but is then executed immediately. We see immediately that the wrong file name resulted from the history expansion, but we can not stop the command (unless it takes somewhat longer).

There is also a bash option for this problem, with which the behavior of bash can be adjusted. If the bash option histverify is set, then commands are displayed after history expansion and are not executed immediately. The user has then the opportunity to correct the result of the replacement:

[user01@aixe01 ~]$ shopt -s histverify
[user01@aixe01 ~]$ rm !?work?:1
[user01@aixe01 ~]$ rm long_file_name.txt

The advantage is that you can now see, before execution, what will actually being executed after the history expansion. However, you now have to confirm each command to be executed after the history expansion by pressing the ENTER key. (Of course, this does not apply to commands that do not contain any characters from the history expansion.)

If you want to use the two bash options presented, they should be entered again in a bash startup file. As usual, we use ~/.bashrc:

[user01@aixe01 ~]$ cat ~/.bashrc

shopt –s histreedit

[user01@aixe01 ~]$