Linux
Linux

If You Use Linux, You Lose Out If You Can’t Do This – Part 1

Hello, everyone, Satoru Miyazaki here. I’ve been involved with Linux for 20 years now. Linux is widely used, but many users don’t make full use of it. So I’d like to introduce some tips that will make you realize, “If you use Linux, you lose out if you can't do this!”

Hello, everyone, Satoru Miyazaki here. I’ve been involved with Linux for 20 years now. Linux is widely used, but many users don’t make full use of it. So I’d like to introduce some tips that will make you realize, “If you use Linux, you lose out if you can’t do this!”

history functions

Linux users who use bash or zsh often use its history functions. But many users only use the ↑↓ cursor keys or press Ctrl-p/Ctrl-n to use history.

Linux’s history functions are extremely powerful tools. So I’ll introduce some amazing ways of using them.

search-history

Do you know about Ctrl-r? When you press Ctrl-r, the prompt (reverse-i-search)`’: appears. Enter a string to search the most recent past entry that contain the string. Press Ctrl-r again to navigate through earlier entries in your history list.

To search forward in history after navigating past entries, use Ctrl-s. However, under usual TTY settings, Ctrl-s is treated as STOP (command to stop input), so you won’t be able use Ctrl-s to search history. If that’s the case, use stty to disable Ctrl-s. While you’re at it, also disable the counterpart of Ctrl-s, Ctrl-q (START=command to begin input).

```
$ stty stop undef
$ stty start undef
$ stty  -a
speed 38400 baud; rows 24; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = <undef>; stop = <undef>; susp = ^Z;
rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke -flusho -extproc
```

Use stty –a to confirm that TTY start/stop have become undefined. You can now search your history backward (reverse-i-search) with Ctrl-r and forward with Ctrl-s.

```
(reverse-i-search)`ls’: ls .git/objects/info/
(i-search)ls': ls info/
```

Symbols for history

Do you know the standard history functions in bash? Pressing the keys I described above is useful for navigating the history list. What’s more, there are history functions that use ‘!’. This symbol is a transplant of the expansion feature in csh. It has become very useful in bash. More information is given in the bash manual. I’ve excerpted a portion below.

Event Designator

An event designator is a reference to a command line entry in the history list.

– !!
   Execute the previous command in the history list.

– !n
   Execute the nth command in the history list (absolute position).

– !-n
   Execute the command n lines back in the history list (relative position).

– !string
   Execute the most recent command in the history list starting with string.

– !?string[?]
   Execute the most recent command in the history list containing string. (The ‘?’ at the end may be omitted if string ends with a newline.)

– !#
   Refer to the entire command line typed immediately before !#. (The input before !# is expanded as-is.)

   ```
$ echo !#
echo echo
echo
   ```

Word Designators

Word designators are used to select the words you desire from the event. The event designator and the word designator are separated by ‘:’. However, ‘:’ may be omitted if the word designator begins with a ‘^’, ‘$’, ‘*’, ‘-’, or ‘%’. Also, a command like ‘!word designator’ displays the last command.

– ‘n’
   The nth argument of the designated event from the history list.

   ```
   $ echo 123 456
   123 456
   $ echo !:2
   echo 456
   456
   $ echo !:0
   echo echo
   echo
   ```

– ‘^’
   The first argument of the designated event from the history list.

– ‘$’
   The last argument of the designated event from the history list.

– ‘x-y’
   xth to yth arguments of the designated event from the history list.
   In case of ‘0-y’, ‘-y’ may be omitted.
   ‘x-$’ indicates the xth to the last argument.

– ‘*’
   All arguments of the designated event from the history list, except the 0th. (If there are no arguments, the string is empty.)

– ‘x*’
   Same as ‘x-$’. xth to the last argument.

– ‘x-‘
   Similar to ‘x*’ but does not include the last argument.

Modifiers

After the word designator, you can add one or more of modifiers to the end of a word designator. Place ‘:’ before each modifier.

– h
   Remove the filename component at the end of the pathname. Only the directory name is displayed (same as dirname).

   ```
   $ ls Vagrant/redmine/setup_redmine.sh
   Vagrant/redmine/setup_redmine.sh
   $ echo !$:h
   echo Vagrant/redmine
   Vagrant/redmine
   ```

– t
   Remove the directory name from the pathname. Only the file name component is displayed (same as basename).

   ```
   $ ls Vagrant/redmine/setup_redmine.sh
   Vagrant/redmine/setup_redmine.sh
   $ echo !$:t
   echo setup_redmine.sh
   setup_redmine.sh
   ```

– r
   Remove the directory name as well as the suffix from the pathname.

   ```
   $ ls Vagrant/redmine/setup_redmine.sh
   Vagrant/redmine/setup_redmine.sh
   $ echo !$:r
   echo Vagrant/redmine/setup_redmine
   Vagrant/redmine/setup_redmine
   ```

– e
   Display only the suffix of the pathname.

   ```
   $ ls Vagrant/redmine/setup_redmine.sh
   Vagrant/redmine/setup_redmine.sh
   $ echo !$:e
   echo .sh
   .sh
   ```

– p
   Display the command only and do not execute it.

   ```
   $ ls Vagrant/redmine/setup_redmine.sh
   Vagrant/redmine/setup_redmine.sh
   $ !!:p
   ls Vagrant/redmine/setup_redmine.sh
   ```

– s/*old*/*new*/

   – The first occurrence of *old* found in the event line is replaced by *new*.
   – After s, any character may be used in place of ‘/’ as the separator character.
   – If ‘&’ is included in *new*, it is replaced by *old*.
   – If \\& is specified after s, & may be used as the separator character.
   – Can also be written as ^*old*^*new*

   ```
   $ echo abcabcdefabcdef
   abcabcdefabcdef
   $ !:s/abc/ABC/
   echo ABCabcdefabcdef
   ABCabcdefabcdef
   $ !:s|def|DEF|
   echo ABCabcDEFabcdef
   ABCabcDEFabcdef
   $ !:s/abcdef/ABC&DEF/
   echo ABCabcDEFABCabcdefDEF
   ABCabcDEFABCabcdefDEF
   $ ^abc^XYZ
   echo ABCXYZDEFABCabcdefDEF
   ABCXYZDEFABCabcdefDEF
   ```

– q
   Quote and display the event.

   ```
   $ echo abcdefdef
   abcdefdef
   $ echo !!:q
   $ echo !!:q
   echo ‘echo ABCabcdefabcdef’
   echo ABCabcdefabcdef
   ```

– x
   Similar to q, but quotes by separating at spaces and newlines within the event line.

   ```
   $ echo ABCabcdefabcdef
   ABCabcdefabcdef
   $ echo !!:x
   echo ‘echo’ ‘ABCabcdefabcdef’
   echo ABCabcdefabcdef
   ```

– &
   Repeat the last substitution.

– g
   Apply the change to the entire event line.

   ```
   $ echo abcabcdefabcdef
   abcabcdefabcdef
   $ !:gs/abc/ABC/
   echo ABCABCdefABCdef
   ```

– G
   Apply the s modifier following this modifier once to each word in the event line.

   ```
   $ echo abcabc defabc def
   abcabc defabc def
   $ !:Gs/abc/XYZ/
   echo XYZabc defXYZ def
   ```

As you can see, by combining event designators, word designators, and modifiers, you can create a variety of strings to use history.

And, by pressing Esc^(history-expand-line), which is set with key binding, you can see the expansion of the event designator, word designator, and modifiers on the command line. This is a convenient way of checking your command construction, so be sure to remember it. 

##history command

Everyone has most likely used the history command to view a list of previously executed commands.

###history options

You can perform the following by adding the options below to the history command.

– -c
   Clear all the entries in the history list.
– -a
   Append all the history lines used in the current session to the history file.
– -n
   Append the history lines not already read from the history file to the current history list.
– -r
   Re-read the history file and append its content to the current history entries.
– -w
   Overwrite history file with the current history list.
– -p
   History substitution is performed on the string following history –p and
   the result is displayed on the standard input. This result is not stored in
   the history list.
– -s
   The string following history –s is added to the list of history entries.

Environment variables used for history

You can modify how the history command operates with several environment variables. Place export in a file like .bashrc.

– HISTFILE
   The filename of the history file. By default it is ~/.bash_history. When you end the bash session, your entries are stored in
   this history file. If you don’t specify this environment variable, the history of your session is not stored in a history fire.
– HISTFILESIZE
   The maximum number of commands stored in the history file. If this maximum number is exceeded, previous commands
   are removed from this file beginning with the oldest commands.
– HISTSIZE
   The number of commands that is remembered in memory in a history list. By default the size is 500 commands.
– HISTTIMEFORMAT
   Usually, when you run the history commands, your entries for the session are not displayed with the time they are executed
   (timestamp). Set HISTTIMEFORMAT using the format strings of strftime(). Timestamps will be saved in the history list.

Finally

Everyone uses history in Linux, but it has functions you didn’t know about, doesn’t it? These functions are all described in man bash. However, many users often use bash without reading the manual. Browse man bash once in a while and try out bash’s different functions!

Part 2

Part 3

Part 4

Satoru Miyazaki

NEXT ARTICLE