Bash – Why can I change bash history

bashcommand history

Why does bash change the history even I'm not executing a command I'm modifying? For example, if I type:

$ echo foo1
foo1
$ echo foo2
foo2
$ echo foo3
foo3

After this, I press up twice, and I get echo foo2 on the prompt. I press 2 and get echo foo22. Now back to the end (empty line) with downdown. If I now search history, I'll see echo foo22 even though I've never executed that command!

However, when I exit the shell and open another one, I see the original, executed commands. I find all this very confusing, counter-intuitive and irritating.

I'd like the history thing to work like this:

  1. Only the commands actually executed are saved to the history.

  2. History is immutable. (Unless explicitly cleared.)

Is there a way to accomplish this?

Edit – this question seems related: Is there any way to undo a bash history modification?

Best Answer

I find all this very confusing, counter-intuitive and irritating.

That's your opinion; I implemented an interactive REPL for a programming language in which each line of history can not only be edited, but has its own independent undo history. So although a command can exist which was never run, you can go back there with up arrow and undo it back to the original.

However, just like in Bash this editing of the history is only saved into the history when you navigate away from the modified line. Not if you edit the line and then re-submit it as a new command without ever having navigated away from it! In that special case, the edits are not saved into the history, because they are being saved as a new history entry.

There is a rhyme and reason to it!

  1. It would be clearly counter-intuitive and irritating not to be allowed to edit a history line before submitting it as a new command.

  2. It would be counter-intuitive and irritating to simply lose your edits to a history line if you navigate away from it to look at another line.

A possible solution might be this: when the user edits a history line, save it in a temporary area representing the new to-be-submitted line (and don't update the history). However:

  1. This would still be counter-intuitive and irritating. The user would not be able to edit a line, hit the up arrow twice to look at a previous line, and then down arrow twice to return to the edit. The user would then see the original unedited line and have to navigate all the way to the front of the history to find the new version of the line in the current ("history zero") edit buffer.

  2. What if the user made two edits in two different history lines? It would be irritating to have the least recent such edit be silently clobbered by the most recent.

The only way to have an immutable history in which you can make multiple temporary edits at the same time, and submit them as new commands in any order, would likely be difficult to present in the current UI paradigm without being confusing. That "current UI paradigm" being that the entire workspace (history plus new entry) is mapped to a single edit window on the screen, with view, if any, any visual clue about where the user is and any state indication.

We would likely need a position indicator (some little number indicating to the user where they are in the history space), an indicator of whether that history line contains temporary modifications; a way to toggle between seeing the modifications or the underlying unchanged line; a way to make the modifications permanent (do mutate history); a way to discard the modifications for a line or range of lines or all lines, etc.

Related Question