Post

3 Rerunning Commands

3 Rerunning Commands

3. Rerunning Commands

All the advice in this book will serve you better if you can type quickly. No matter how knowledgeable you are, if you type 40 words per minute and your equally knowledgeable friend types 120, they’re set up to work three times as fast as you. Search the web for “typing speed test” to measure your speed, then search for “typing tutor” and build a lifelong skill. Try to reach 100 words per minute. It’s worth the effort.

Linux Command Line Program: gtypist

Viewing the command History

1
2
3
4
5
6
7
8
9
$ history
 1000  cd $HOME/Music
 1001  ls
 1002  mv jazz.mp3 jazzy-song.mp3
 1003  play jazzy-song.mp3
 ⋮                                      Omitting 477 lines
 1481  cd
 1482  firefox https://google.com
 1483  history                         Includes the command you just ran
1
2
3
4
$ history 3                            Print the 3 most recent commands
 1482  firefox https://google.com
 1483  history
 1484  history 3
1
2
$ history | less                      Earliest to latest entry
$ history | sort -nr | less           Latest to earliest entry
1
2
3
4
5
6
7
$ history | grep -w cd
 1000  cd $HOME/Music
 1092  cd ..
 1123  cd Finances
 1375  cd Checking
 1481  cd
 1485  history | grep -w cd
1
2
# To clear (delete) the history for the current shell:
$ history -c

Recalling Commands from the History

Cursoring Through History

up arrow key

down arrow key

Enter to run it.

On a full-sized American QWERTY keyboard, I place my right ring finger on the up arrow and my right index finger on Enter to tap both keys efficiently. (Try it.)

1
2
3
$ echo $HISTSIZE
500
$ HISTSIZE=10000

Store unlimited commands by setting the value to -1.

1
$ HISTCONTROL=ignoredups

If the value is ignoredups (which I recommend), then repeated commands are not appended if they are consecutive.

Whenever an interactive shell exits, it writes its history to the file $HOME/.bash_history or whatever path is stored in the shell variable HISTFILE:

1
2
$ echo $HISTFILE
/home/smith/.bash_history

The variable HISTFILESIZE controls how many lines of history are written to the file.

If you change HISTSIZE to control the size of the history in memory, consider updating HISTFILESIZE as well:

1
2
3
$ echo $HISTFILESIZE
500
$ HISTFILESIZE=10000

History Expansion

Two exclamation points in a row (“bang bang”) evaluates to the immediately previous command:

1
2
3
4
5
$ echo Efficient Linux
Efficient Linux
$ !!                            "Bang bang" = previous command
echo Efficient Linux            The shell helpfully prints the command being run
Efficient Linux

To refer to the most recent command that began with a certain string, place an exclamation point in front of that string:

1
2
3
$ !grep
grep Perl animals.txt
alpaca	Intermediate Perl	2012	Schwartz, Randal

To refer to the most recent command that contained a given string somewhere, not just at the beginning of the command, surround the string with question marks:

1
2
3
4
5
$ !?grep?
history | grep -w cd
 1000  cd $HOME/Music
 1092  cd ..
⋮
1
2
3
4
5
6
7
$ history | grep hosts
 1203  cat /etc/hosts
$ !1203                         The command at position 1203
cat /etc/hosts
127.0.0.1       localhost
127.0.1.1       example.oreilly.com
::1             example.oreilly.com
1
2
3
4
5
6
7
8
9
10
$ history
 4197  cd /tmp/junk
 4198  rm *
 4199  head -n2 /etc/hosts
 4199  cd
 4200  history
$ !-3                         The command you executed three commands ago
head -n2 /etc/hosts
127.0.0.1       localhost
127.0.1.1       example.oreilly.com
1
2
3
4
5
6
7
8
9
$ !-3:p
head -n2 /etc/hosts              Printed, not executed

$ !-3:p
head -n2 /etc/hosts              Printed, not executed, and appended to history
$ !!                             Run the command for real
head -n2 /etc/hosts              Printed and then executed
127.0.0.1       localhost
127.0.1.1       example.oreilly.com
1
2
3
4
5
6
7
8
$ ls -l /etc | head -n3       Run any command
total 1584
drwxr-xr-x  2 root     root       4096 Jun 16 06:14 ImageMagick-6/
drwxr-xr-x  7 root     root       4096 Mar 19  2020 NetworkManager/

$ echo "!!" | wc -w           Count the words in the previous command
echo "ls -l /etc | head -n3" | wc -w
6
1
2
3
4
5
6
7
8
9
10
11
12
# History Expressions Don’t Appear in the Command History
$ ls               Run any command
hello.txt
$ cd Music         Run some other command
$ !-2              Use history expansion
ls
song.mp3
$ history          View the history
 1000  ls
 1001  cd Music
 1002  ls          "ls" appears in the history, not "!-2"
 1003  history

Never Delete the Wrong File Again

1
2
3
4
5
$ alias rm='rm -i'                  Often found in a shell configuration file
$ rm *.txt
/bin/rm: remove regular file 'a.txt'? y
/bin/rm: remove regular file 'b.txt'? y
/bin/rm: remove regular file 'c.txt'? y
  1. Verify. Before running rm, run ls with the desired pattern to see which files match.

    1
    2
    
    $ ls *.txt
    a.txt   b.txt   c.txt
    
  2. Delete. If the output of ls looks correct, run rm !$ to delete the same files that were matched.

    1
    2
    
    $ rm !$
    rm *.txt
    

    !$ (“bang dollar”) means the final word that you typed in the previous command.

1
2
3
4
$ head myfile.txt
(first 10 lines of the file appear)
$ rm !$
rm myfile.txt
1
2
3
4
$ ls *.txt *.o *.log
a.txt   b.txt   c.txt   main.o   output.log   parser.o
$ rm !* 
rm *.txt *.o *.log

!* (Bang Star) matches all arguments you typed in the previous command.

Incremental Search of Command History

  1. At the shell prompt, press Ctrl-R (the R stands for reverse incremental search).
  2. Start typing any part of a previous command—beginning, middle, or end.
  3. With each character you type, the shell displays the most recent historical command that matches your typing so far.
  4. When you see the command you want, press Enter to run it.

Press Ctrl-R a second time. This keystroke causes the shell to jump to the next matching command in the history.

Here are a few more tricks with incremental search:

  • To recall the most recent string that you searched for and executed, begin by pressing Ctrl-R twice in a row.
  • To stop an incremental search and continue working on the current command, press the Escape key, or Ctrl-J, or any key for command-line editing, such as the left or right arrow key.
  • To quit an incremental search and clear the command line, press Ctrl-G or Ctrl-C.

Command-Line Editing

Cursoring Within a Command

Cursor keys for simple command-line editing:

KeystrokeAction
Left arrowMove left by one character
Right arrowMove right by one character
Ctrl + left arrowMove left by one word
Ctrl + right arrowMove right by one word
HomeMove to beginning of command line
EndMove to end of command line
BackspaceDelete one character before the cursor
DeleteDelete one character beneath the cursor

History Expansion with Carets

1
2
3
4
5
6
$ md5sum *.jg | cut -c1-32 | sort | uniq -c | sort -nr
md5sum: '*.jg': No such file or directory
$ ^jg^jpg
$ ^jg^jpg
md5sum *.jpg | cut -c1-32 | sort | uniq -c | sort -nr

Notice that the shell helpfully prints the new command before executing it, which is standard behavior for history expansion.

1
2
3
4
s/source/target/

$ !!:s/jg/jpg/
$ !md5sum:s/jg/jpg/

Emacs- or Vim-Style Command-Line Editing

Vim-style editing:

1
$ set -o vi

Emacs-style editing:

1
$ set -o emacs

Keystrokes for Emacs- or Vim-style editing:

ActionEmacsVim
Move forward by one characterCtrl-fl
Move backward by one characterCtrl-bh
Move forward by one wordMeta-fw
Move backward by one wordMeta-bb
Move to beginning of lineCtrl-a0
Move to end of lineCtrl-e$
Transpose (swap) two charactersCtrl-txp
Transpose (swap) two wordsMeta-tn/a
Capitalize word (uppercase first letter)Meta-cn/a
Uppercase to end of wordMeta-un/a
Lowercase to end of wordMeta-ln/a
Change case of the current charactern/a~
Insert the next character verbatim, including control charactersCtrl-vCtrl-v
Delete forward by one characterCtrl-dx
Delete backward by one characterBackspace or Ctrl-hX
Cut forward by one wordMeta-ddw
Cut backward by one wordMeta-Backspace or Ctrl-wdb
Cut from cursor to beginning of lineCtrl-ud^
Cut from cursor to end of lineCtrl-kD
Delete the entire lineCtrl-e Ctrl-udd
Paste (yank) the most recently deleted textCtrl-yp
Paste (yank) the next deleted text (after a previous yank)Meta-yn/a
Undo the previous editing operationCtrl-_u
Undo all edits made so farMeta-rU
Switch from insertion mode to command moden/aEscape
Switch from command mode to insertion moden/ai
Abort an edit operation in progressCtrl-gn/a
Clear the displayCtrl-lCtrl-l
Move ‘back’ through the history list, fetching the previous command.Ctrl-p 
Move ‘forward’ through the history list, fetching the next command.Ctrl-n 

https://www.gnu.org/software/bash/manual/html_node/Bindable-Readline-Commands.html

https://catonmat.net/ftp/bash-vi-editing-mode-cheat-sheet.pdf

This post is licensed under CC BY 4.0 by the author.