Skip to content
VLSI Mentor

Linux & Bash · Part I · Module 1 · Linux, the Shell and the Command Line

History and Editing the Line You Are On

This chapter is not here as a productivity tip. Everything in Part I is learned by the same loop — run something, read what happened, change one thing, run it again — and a reader who retypes each attempt from scratch both practises more slowly and introduces fresh typing mistakes into every iteration. Recalling and editing is the mechanism that makes the rest of the course cheap to practise. It also contains the one feature in this module that genuinely deserves caution: an exclamation-mark expansion is committed to running before you have had a chance to read what it produced.

Foundation13 min readLinuxBashPart IFundamentalsCommand Line

Part I · Module 1 · Chapter 1.8 · History and Editing the Line You Are On

1. The Shell Remembers

Bash keeps a numbered list of the command lines you have entered.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
history
Azvya Education Pvt. Ltd.VLSI Mentor
Representative output — the tail of a session
  497  hostname
  498  whoami
  499  pwd
  500  ls -lh /etc
  501  type -a echo
  502  history

Each line has a number, and the list survives between sessions: on exit, Bash writes it to a file in your home directory — conventionally ~/.bash_history — and reads it back when a new shell starts. That is why a server you have not logged into for a week still remembers what you were doing.

How much is kept, whether duplicates are stored, and how concurrent sessions merge are all controlled by shell variables, which are Module 10's subject. Two properties matter now, and both are limitations:

History is per-shell until it is written. Two sessions open at once each hold their own list in memory. Depending on configuration, one can overwrite the other's file on exit, and lines can be lost.

History is a convenience, not a record. It can be edited, truncated, disabled or lost. It is the wrong thing to rely on for "what exactly did I run last Tuesday" — Part II addresses that properly by having automation record its own commands, because a question that matters deserves a better answer than a shell's memory.

2. Recall Before Retype

The least impressive and most used feature: the Up arrow steps back through history, Down returns.

The reason to form the habit is not speed. A recalled line is the line that actually ran, character for character. A retyped line is a new line that you believe is the same — and when the first attempt was long, that belief is where a fresh mistake comes from.

So: debug by recalling the previous attempt and changing the one thing you meant to change.

3. Editing the Line You Are On

Once a line is recalled, you need to move around it. Arrow keys work, one character at a time, and that is enough for a short line and painful for a long one.

These are the keys that earn their place:

KeyEffect
Ctrl-Ajump to the start of the line
Ctrl-Ejump to the end of the line
Alt-B / Alt-Fmove back / forward one word
Ctrl-Wdelete the word before the cursor
Ctrl-Udelete from the cursor back to the start
Ctrl-Kdelete from the cursor to the end
Ctrl-Ypaste back what you last deleted with the keys above
Ctrl-Lclear the screen, keeping the line you are typing
Ctrl-Cabandon this line without running it

Three of these change how you work rather than saving keystrokes.

Ctrl-W is the fix for a mistyped last word: one key removes it, and you retype only that word.

Ctrl-U then retype is better than holding Backspace when a line is beyond saving — and Ctrl-U, Ctrl-Y together make it a move rather than a deletion, which is how you set a half-written line aside, run something else, and bring it back.

Ctrl-C is the honest way out. Chapter 1.3 explained what Ctrl-C does to a running program; at a prompt with no program running, it abandons the line you are composing and gives you a fresh one. Use it instead of deleting a line you have decided against — there is no risk of accidentally pressing Enter on a half-edited command.

Two honest caveats. These bindings come from Readline, the line-editing library Bash uses, and they are configurable — Bash also offers a vi-style editing mode for people who prefer it. And a few key combinations are intercepted or remapped by the terminal emulator before Bash ever sees them, which is why Ctrl-Left and Ctrl-Right move by word in some terminals and do nothing in others. That is a terminal setting, per Chapter 1.3, not a Bash one.

4. Reverse Search: Ctrl-R

The single highest-value key in the chapter. Press Ctrl-R and start typing any part of a command you ran before; Bash searches backwards through history and shows the most recent match.

Azvya Education Pvt. Ltd.VLSI Mentor
Representative display while searching
(reverse-i-search)`etc': ls -lh /etc

The prompt changes to show what you have typed (etc) and the matching line it found. From there:

  • keep typing to narrow the match;
  • Ctrl-R again to step to the next older match;
  • Enter to run the match as it stands;
  • Left or Right arrow to accept the match into the line for editing without running it;
  • Ctrl-G to cancel and return to your empty prompt.

That fourth option is the one worth internalising. Ctrl-R, then an arrow key, gives you the old command sitting in your line, where you can read it, change it, and only then press Enter. It is the safe way to re-run something you are not completely sure of.

5. Finding Things in History

Two ways to search without Ctrl-R, both useful when you want to look rather than to run.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
history 5
Azvya Education Pvt. Ltd.VLSI Mentor
Representative output — the last five entries
  499  pwd
  500  ls -lh /etc
  501  type -a echo
  502  history
  503  history 5

A numeric argument limits the output to that many recent lines, which is the usual way to use it. Searching the whole list for a word is a job for a pipeline, and Module 12 and Module 14 together give you that properly:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
history | grep hostname

That line uses a pipe, which is Module 12's subject. It is shown here because it is the natural thing to want and because recognising it now costs nothing: history produces the list, and grep keeps the matching lines.

6. History Expansion: the ! Forms

Bash can refer to earlier commands directly. The forms are short, genuinely useful, and carry a hazard that the next section is entirely about.

FormMeans
!!the previous command line, in full
!501history entry number 501
!lsthe most recent line starting with ls
!$the last word of the previous line
!*all the arguments of the previous line

!$ is the one that repays learning first, because of a pattern you will hit constantly: name a file in one command, then act on the same file in the next.

Azvya Education Pvt. Ltd.VLSI Mentor
Representative session — !$ reuses the last word
engineer@server:~$ ls -l /etc/os-release
-rw-r--r-- 1 root root 389 Jan 18 08:03 /etc/os-release
engineer@server:~$ cat !$
cat /etc/os-release
NAME="Ubuntu"
VERSION="22.04.4 LTS (Jammy Jellyfish)"

Read the middle of that session carefully. You typed cat !$. Bash printed cat /etc/os-release — the line after expansion — and then ran it. The echo is the shell showing you what it decided your line meant.

!! behaves the same way:

Azvya Education Pvt. Ltd.VLSI Mentor
Representative session — !! repeats the previous line
engineer@server:~$ pwd
/home/engineer
engineer@server:~$ !!
pwd
/home/engineer

Where !! is genuinely valuable is when the previous command failed because it needed elevated privileges, and you want to repeat it unchanged with a prefix:

Azvya Education Pvt. Ltd.VLSI Mentor
Representative pattern
engineer@server:~$ sudo !!

Retyping a long command correctly under those circumstances is exactly the situation in which people make a new mistake.

7. Why ! Deserves Caution

Now the part that makes this a fundamentals chapter rather than a tips list.

History expansion runs immediately. Bash substitutes the old text into your line and executes it in the same keystroke. The echoed line is shown to you as it runs, not before — it is a record, not a confirmation. There is no pause and nothing to cancel.

Consider what that means in a realistic sequence:

Azvya Education Pvt. Ltd.VLSI Mentor
Representative — a pattern worth not building a habit around
engineer@server:~$ rm -rf build
engineer@server:~$ ls
engineer@server:~$ cd ../other-project
engineer@server:~$ !rm

!rm finds the most recent line beginning with rm and runs it — in the directory you are in now, which is not the directory you were in when you typed it. The command is correct, your memory of it is correct, and the target is wrong. Chapter 1.4's point about the working directory being the silent half of every command is exactly the mechanism.

There is a safe way to look first. Appending :p prints the expansion without running it:

Azvya Education Pvt. Ltd.VLSI Mentor
Representative session — :p prints, and does not run
engineer@server:~$ pwd
/home/engineer
engineer@server:~$ !!:p
pwd
engineer@server:~$

pwd was printed and not executed — notice that no directory was output. The expanded line is also placed in your history, so a single Up arrow brings it back for you to read and run deliberately.

8. The Exclamation-Mark Surprise

This one catches everybody exactly once, and it is better to meet it here.

In an interactive shell, ! triggers history expansion wherever it appears, including inside double quotes:

Azvya Education Pvt. Ltd.VLSI Mentor
Representative session — a real interactive Bash
bash-3.2$ echo "it worked!"
bash: !": event not found

Nothing is wrong with the quoting. Bash saw ! followed by ", tried to interpret it as a history reference, found no such history entry, and refused the whole line rather than running it. The command never ran.

Three things resolve it:

  • single quotes, which suppress history expansion: echo 'it worked!';
  • a backslash before the exclamation mark: echo "it worked\!";
  • ending the word there, since ! followed by a space or end-of-line is not special.

And one precision worth having, because it prevents a wrong generalisation: this only happens in interactive shells. History expansion is off by default when Bash runs a script, so the same line inside a script prints it worked! exactly as written. A difference in behaviour between your prompt and your script is a real category of confusion, and this is one of the few genuine cases of it.

9. Why This Matters Beyond Convenience

Two connections to real work, neither requiring semiconductor knowledge.

Reproducing a command exactly. "What did you run?" is the first question asked about any result that looks wrong, and a reconstruction from memory is not an answer. Recalling the real line is better. Better still is not depending on history at all: Part II has a chapter on recording the exact command a run used into the run's own directory, precisely because shell history is per-session, editable and easily lost.

Interactive habits become script bugs. A command you built interactively by recalling and editing is a command whose final form you may never have read in full. When that line is later pasted into automation, anything it depended on — the working directory you were in, a file that existed at the time — travels with it silently. Module 20 is about making scripts state their assumptions; the discipline starts with reading the line before you press Enter.

10. Check Your Understanding

Question 1. Why is recalling a previous command with the Up arrow safer than retyping it, even when you remember it correctly?

Question 2. You press Ctrl-R, type tar, and see a match you want to inspect before running. Which key accepts it into the line without running it, and which key would have run it immediately?

Question 3. echo "done!" fails with event not found. Explain what Bash tried to do, and give two ways to write the line so it works.

Question 4. Does the failure in Question 3 also occur inside a script? Explain why or why not.

Question 5. You ran rm -rf output in one directory, changed to another, and typed !rm. What runs, and against what? Which earlier chapter's concept explains the danger?

Question 6. What does !!:p do that !! does not, and why is that the difference between a safe and an unsafe re-run?

11. Remember

  • The shell keeps a numbered history and saves it between sessions. How much, and how concurrent sessions merge, is configuration (Module 10).
  • History is a convenience, not a record. It can be lost, edited or overwritten by another session. Anything that matters should record itself.
  • Recall and edit, do not retype. A recalled line is the line that ran; a retyped one is a new line you believe is the same.
  • Ctrl-W, Ctrl-U, Ctrl-A, Ctrl-E turn a long line from a chore into an edit. Ctrl-C abandons a line safely; Ctrl-D at an empty prompt ends the shell.
  • Ctrl-R is the highest-value key, and Ctrl-R followed by an arrow key — accept into the line, read, then Enter — is the safe way to re-run anything.
  • !$ reuses the last word of the previous line, which fits the inspect-then-act pattern you will use constantly.
  • History expansion runs immediately. The echoed line is a record, not a confirmation. Never reach a destructive command that way.
  • !!:p prints without running, and leaves the expansion in history for a deliberate Up-arrow re-run.
  • ! is special inside double quotes in an interactive shell — and not in a script. Single quotes or a backslash fix it; Module 9 explains the whole mechanism.
  • Line editing and history belong to the shell, not the terminal — which is why they behave identically over SSH, and why a few key combinations depend on your terminal instead.

That completes Module 1. You can now say what Linux is in three precise words rather than one vague one; describe what the shell does with a line; separate the terminal, the shell and the program; orient yourself on an unfamiliar machine; decompose an unfamiliar command; find authoritative documentation for it; tell a builtin from a program and explain why that distinction exists; and practise all of it without retyping. Module 2 takes the next step and makes the filesystem precise: one tree, and exactly how to point at any place in it.

Where this fits

Part of the Linux & Bash curriculum.