覚えておくと案外役に立つbashのhistory機能の使い方いろいろ

CentOSやUbuntuといったLinuxをコンソールで使っていれば、必ず使ったことがあるであろうbashのhistory機能。
この機能、結構いろいろなことができるので、今回はそれらを紹介していく。

1.基本的な使い方

ただhistoryコマンドを実行して今までの履歴を確認する、といった使い方。
一度は使ったことがあるだろう。

[test@BS-PUB-CENT7-01 ~]$ history
    1  cd
    2  passwd
    3  clear
    4  exit
    5  passwd
    6  clear
    7  pwgen
    8  clear
    9  exit
   10  passwd
   11  clear
   12  passwd -S ユーザID
   13  exit
   14  cd
   15  history

2.履歴番号を指定して再度そのコマンドを実行する

historyコマンドで出力された内容から、再度実行したい履歴番号を指定して実行することができる。

!履歴番号
[test@BS-PUB-CENT7-01 ~]$ history
    1  cd
    2  passwd
    3  clear
    4  exit
    5  passwd
    6  clear
    7  pwgen
    8  clear
    9  exit
   10  passwd
   11  clear
   12  passwd -S ユーザID
   13  exit
   14  cd
   15  history
   16  clear
   17  ls -la /tmp/
   18  clear
   19  history
[test@BS-PUB-CENT7-01 ~]$ <span style="color: #ff0000;">!17
ls -la /tmp/</span>
合計 52
drwxrwxrwt. 11 root root 4096  6月 25 17:50 .
dr-xr-xr-x. 18 root root 4096  4月  3 19:54 ..
drwxrwxrwt.  2 root root    6  6月 25 15:02 .ICE-unix
drwxrwxrwt.  2 root root    6  6月 25 15:02 .Test-unix
drwxrwxrwt.  2 root root    6  6月 25 15:02 .X11-unix
drwxrwxrwt.  2 root root    6  6月 25 15:02 .XIM-unix
drwxrwxrwt.  2 root root    6  6月 25 15:02 .font-unix
drwxr-xr-x.  2 root root    6  6月 25 06:49 aaa
drwxr-xr-x.  2 root root    6  6月 25 06:49 bbb
drwxr-xr-x.  3 root root   27  6月 25 06:50 ccc
drwxr-xr-x.  2 root root   14  6月 25 06:54 empty
-rw-r--r--.  1 root root    2  6月 25 06:50 test1
-rw-r--r--.  1 root root  162  5月 26 08:23 test1.txt
-rw-r--r--.  1 root root   25  6月 21 08:53 test123
-rw-r--r--.  1 root root   85  6月 25 17:40 test1234
-rw-r--r--.  1 root root   24  6月 25 17:45 test12345
-rw-r--r--.  1 root root   26  6月 24 07:30 test123_2
-rw-r--r--.  1 root root   25  6月 24 07:38 test123_3
-rw-r--r--.  1 root root    0  6月 25 06:50 test2
-rw-r--r--.  1 root root   31  6月 24 08:06 test2.txt
-rw-r--r--.  1 root root   53  6月 15 23:36 test6.txt
-rw-r--r--.  1 root root   48  6月 16 05:49 test7.txt
-rw-r--r--.  1 root root   71  6月 25 17:50 test_1

このとき、「○個前に使ったコマンド」といった指定方法も可能だ。

!-○
[test@BS-PUB-CENT7-01 ~]$ history | tail -2
   32  ls -la /tmp/
   33  history | tail -2
[test@BS-PUB-CENT7-01 ~]$ !-2
ls -la /tmp/
合計 52
drwxrwxrwt. 11 root root 4096  6月 25 17:50 .
dr-xr-xr-x. 18 root root 4096  4月  3 19:54 ..
drwxrwxrwt.  2 root root    6  6月 25 15:02 .ICE-unix
drwxrwxrwt.  2 root root    6  6月 25 15:02 .Test-unix
drwxrwxrwt.  2 root root    6  6月 25 15:02 .X11-unix
drwxrwxrwt.  2 root root    6  6月 25 15:02 .XIM-unix
drwxrwxrwt.  2 root root    6  6月 25 15:02 .font-unix
drwxr-xr-x.  2 root root    6  6月 25 06:49 aaa
drwxr-xr-x.  2 root root    6  6月 25 06:49 bbb
drwxr-xr-x.  3 root root   27  6月 25 06:50 ccc
drwxr-xr-x.  2 root root   14  6月 25 06:54 empty
-rw-r--r--.  1 root root    2  6月 25 06:50 test1
-rw-r--r--.  1 root root  162  5月 26 08:23 test1.txt
-rw-r--r--.  1 root root   25  6月 21 08:53 test123
-rw-r--r--.  1 root root   85  6月 25 17:40 test1234
-rw-r--r--.  1 root root   24  6月 25 17:45 test12345
-rw-r--r--.  1 root root   26  6月 24 07:30 test123_2
-rw-r--r--.  1 root root   25  6月 24 07:38 test123_3
-rw-r--r--.  1 root root    0  6月 25 06:50 test2
-rw-r--r--.  1 root root   31  6月 24 08:06 test2.txt
-rw-r--r--.  1 root root   53  6月 15 23:36 test6.txt
-rw-r--r--.  1 root root   48  6月 16 05:49 test7.txt
-rw-r--r--.  1 root root   71  6月 25 17:50 test_1

なお、直前のコマンドを再実行する場合は、以下でできる。

!!
[test@BS-PUB-CENT7-01 ~]$ ls -la /home/test
合計 16
drwx------. 2 test test  79  5月 17 08:48 .
drwxr-xr-x. 3 root root  17  5月 15 18:49 ..
-rw-------. 1 test test  92  5月 28 21:47 .bash_history
-rw-r--r--. 1 test test  18 11月 20  2015 .bash_logout
-rw-r--r--. 1 test test 193 11月 20  2015 .bash_profile
-rw-r--r--. 1 test test 231 11月 20  2015 .bashrc
[test@BS-PUB-CENT7-01 ~]$ !!
ls -la /home/test
合計 16
drwx------. 2 test test  79  5月 17 08:48 .
drwxr-xr-x. 3 root root  17  5月 15 18:49 ..
-rw-------. 1 test test  92  5月 28 21:47 .bash_history
-rw-r--r--. 1 test test  18 11月 20  2015 .bash_logout
-rw-r--r--. 1 test test 193 11月 20  2015 .bash_profile
-rw-r--r--. 1 test test 231 11月 20  2015 .bashrc

3.指定したコマンドで最後に使った履歴を再実行する

以下のようにコマンドを実行することで、指定したコマンドで最後に実行した内容を再実行させることができる。

!コマンド
[test@BS-PUB-CENT7-01 ~]$ ps
  PID TTY          TIME CMD
 2673 pts/2    00:00:00 bash
 2729 pts/2    00:00:00 ps
[test@BS-PUB-CENT7-01 ~]$ ps -ef | tail -2
test      2730  2673  0 19:17 pts/2    00:00:00 ps -ef
test      2731  2673  0 19:17 pts/2    00:00:00 tail -2
[test@BS-PUB-CENT7-01 ~]$ !ps
ps -ef | tail -2
test      2732  2673  0 19:17 pts/2    00:00:00 ps -ef
test      2733  2673  0 19:17 pts/2    00:00:00 tail -2

「!?コマンド名」とすることで、途中まで入力されたコマンド名から、マッチした最後に実行されたコマンドが再実行される。

!?コマンド名(途中まで)
[test@BS-PUB-CENT7-01 ~]$ cat /tmp/test1.txt | datamash transpose
id name prefecture value        1 aaa 1 123     2 bbb 2 544     3 ccc 1 65745   4 ddd 1 122    5 eee 2 222     6 fff 1 444     7 ggg 3 566     8 hhh 4 111     9 iii 3 12      10 bbb 2 1243  11 ddd 1 4423
[test@BS-PUB-CENT7-01 ~]$ !?ca
cat /tmp/test1.txt | datamash transpose
id name prefecture value        1 aaa 1 123     2 bbb 2 544     3 ccc 1 65745   4 ddd 1 122    5 eee 2 222     6 fff 1 444     7 ggg 3 566     8 hhh 4 111     9 iii 3 12      10 bbb 2 1243  11 ddd 1 4423

また、「!% キーワード」とすることで、「!?コマンド名」で見つかったコマンドを使いまわすことができる。

[test@BS-PUB-CENT7-01 ~]$ history | grep pw
    7  pwgen
  100  pwgen
  101  pwgen -n 1
  103  history | grep pw
  104  pwgenpw
  106  history | grep pw
  108  pwgen
  110  history | grep pw
[test@BS-PUB-CENT7-01 ~]$ !?pwg
pwgen
coow9Nev Eifiw4ra Aethai4z ohhahn6U jaic5Phu Choh3ahb ohz9Geu6 Eid1pahy
OoQu6Nee phaeSh6y Eohucoh4 OhMohPh5 cheiPoh7 ohchu8Ae Jooph7uo yal2uH1G
que8Vah3 aevae8Eo eiKa3Eem thai4Rae peeFee7a chaiFui7 eequeeN2 xo5Seiph
Kie1xeiy wae1PeeM ahcho2Hu ash0aSis dee1wo0E ReR6ohpi Ig2autaz choh4Udi
iecho1Oh aeLoo0wa Guag8Pha suChoo2i nieDa6Ch deiL0avo ool0uQu3 ocieN9ei
Ahghe8Qu Queeh4Oo eu0Lu4pa ab5Aechu Bachea0i iuy5go4E Kood4Rah aigh2Phu
leiT3esh waa6Nai0 Ughah6ie Sha3ahPh ezejoo2A Oh7weile iey2Ail6 ahZu2eeM
aecahTh9 iRiar3oh urae2Pha thoh5Oqu Eidohph3 eu2Eixei EiXu5Sha coh0Eo8l
Gat7maiz aeT9ahwe aih2aZep yeY4wuuT gouK8phe tae6Yiiw thoh0Quu ieteeNg3
Peih8apo yoNg1loo Aij7chu6 Phoh2pux ieN2aigh iY7einea ohL3toph zoon5Aem
Heel0roB ashiu8Fo Xae7io5y oiD9Obee xai0Jair eteiH2Oo bahg1uLi eeg4uF3o
ahRee3ta geeC3bei iyoo2Eez isae7Ti4 eine5Tie aShe0cio Iengie9z ZioJie2o
vaiKu9ah lahxa5Pa oba0Oeye Eiz2haiM ogh8OoRo gaixoh8H thie6ISo Va6Jee9U
ex1Ieboo Ootha8Im ohXi2foh ieTh2aew uphaeLo9 koHaiG0t JoTh0aiZ ahQuo8ei
aoShi0ph izooNoo0 uur0Ieju Cair9tif Veech0zo rahh7Ood Zoo9Ua3a ootu2Reg
ooChei4t shieK2Pi Nei3ahph Fuyez1Ka aef9Ahxo xe5Eejah liu0OhGh cah3goNg
ae9AhN9u rooR5esh chai7ooK fe9iKeng ooM0Echi qua6tuNg ohme8Oos Weet8aed
iez1saeL KeiH0Thu AiJ2Oiqu nee4Shio Fe3ohk2G vei1no9E baiXeeh8 Kiewai5d
Ue0naid2 ie2Cie1W JeLeim6E lo4ohboC Imohgh9E iejaiX4p haekoh4O Osh2eesh
chei9Zoo rae8aeDi voo3YaiH aeLo6chu ETho1wa8 aiD3AeGa Aitil4vi pee7louK
[test@BS-PUB-CENT7-01 ~]$ !% -n1
pwgen -n1
igohNg4e

4.直前に使用したコマンドの引数を再利用する

直前に使用したコマンドの最後の引数を再利用する場合、引数を利用する箇所で「!$」と記述すればよい。

!$
[test@BS-PUB-CENT7-01 ~]$ cat /tmp/test1.txt
id name prefecture value
1 aaa 1 123
2 bbb 2 544
3 ccc 1 65745
4 ddd 1 122
5 eee 2 222
6 fff 1 444
7 ggg 3 566
8 hhh 4 111
9 iii 3 12
10 bbb 2 1243
11 ddd 1 4423
[test@BS-PUB-CENT7-01 ~]$ ls -la !$
ls -la /tmp/test1.txt
-rw-r--r--. 1 root root 162  5月 26 08:23 /tmp/test1.txt

最初の引数を利用する場合は、「!^」で利用できる。

!^
[test@BS-PUB-CENT7-01 ~]$ ls /tmp/test1.txt /tmp/test1
/tmp/test1  /tmp/test1.txt
[test@BS-PUB-CENT7-01 ~]$ cat !^
cat /tmp/test1.txt
id name prefecture value
1 aaa 1 123
2 bbb 2 544
3 ccc 1 65745
4 ddd 1 122
5 eee 2 222
6 fff 1 444
7 ggg 3 566
8 hhh 4 111
9 iii 3 12
10 bbb 2 1243
11 ddd 1 4423

複数の引数のうち、○番目の引数を指定したい場合は、以下のように指定する。

!:○
[test@BS-PUB-CENT7-01 ~]$ ls /tmp/test123 /tmp/test1234 /tmp/test123_2
/tmp/test123  /tmp/test1234  /tmp/test123_2
[test@BS-PUB-CENT7-01 ~]$ ls -la !:2
ls -la /tmp/test1234
-rw-r--r--. 1 root root 85  6月 25 17:40 /tmp/test1234

すべての引数を取得する場合は、以下のようにする。

!*
[test@BS-PUB-CENT7-01 ~]$ ls /tmp/test123 /tmp/test1234 /tmp/test123_2
/tmp/test123  /tmp/test1234  /tmp/test123_2
[test@BS-PUB-CENT7-01 ~]$ echo !*
echo /tmp/test123 /tmp/test1234 /tmp/test123_2
/tmp/test123 /tmp/test1234 /tmp/test123_2

5.以前使用したコマンドの引数をそのまま再利用する

直前だけでなく、以前使用したコマンドの引数を再利用する場合、各引数は以下のように指定する。
結構多いので、とりあえず一覧っぽくまとめてみた。

!!:^ # 直前のコマンドの最初の引数
!!:○ # 直前のコマンドの○番目の引数
!!:○-○ # 直前のコマンドの○番目から○番目の引数
!!:$ # 直前のコマンドの最後の引数
!コマンド:^ # 指定したコマンドが最後に実行された際の最初の引数
!コマンド:○ # 指定したコマンドが最後に実行された際の○番目の引数
!コマンド:○-○ # 指定したコマンドが最後に実行された際の○番目から○番目の引数
!コマンド:$ # 指定したコマンドが最後に実行された際の最後の引数
!履歴番号:^ # 指定した履歴番号で最後に実行された際の最初の引数
!履歴番号:○ # 指定した履歴番号で最後に実行された際の○番目の引数
!履歴番号:○-○ # 指定した履歴番号で最後に実行された際の○番目から○番目の引数
!履歴番号:$ # 指定した履歴番号で最後に実行された際の最後の引数
[test@BS-PUB-CENT7-01 ~]$ ls /tmp/test123 /tmp/test1234 /tmp/test123_2
/tmp/test123  /tmp/test1234  /tmp/test123_2
[test@BS-PUB-CENT7-01 ~]$ cat !:2
cat /tmp/test1234
 'test message1'
 'test message2'
 'test message3'
 'test message4'
 'test message5'
[test@BS-PUB-CENT7-01 ~]$ cat !ls:$
cat /tmp/test123_2

1111
222

3333

33333

6.以前使用したコマンドの引数(PATH)を加工して利用する

以前使用したコマンドの、PATHを指定した引数を加工して再利用する場合、以下のようにする。
(コマンドや利用する引数など、前項に合わせて書き換え可能)

!コマンド:○:h # 指定したコマンドの○番目の引数のPATHで、ディレクトリ名だけを利用する
!コマンド:○:t # 指定したコマンドの○番目の引数のPATHで、ファイル名だけを利用する
!コマンド:○:r # 指定したコマンドの○番目の引数のPATHで、拡張子を削除する
[test@BS-PUB-CENT7-01 ~]$ cat /tmp/aaa/test.txt
111
222
333

[test@BS-PUB-CENT7-01 ~]$ echo !cat:$:h
echo /tmp/aaa
/tmp/aaa
[test@BS-PUB-CENT7-01 ~]$ echo !cat:$:t
echo test.txt
test.txt
[test@BS-PUB-CENT7-01 ~]$ echo !cat:$:r
echo /tmp/aaa/test
/tmp/aaa/test

7.以前使用した履歴の内容を置換する

以前使用したコマンドの引数をsedのように置換して利用する場合、以下のようにする。

!!:s/置換前/置換後/
[test@BS-PUB-CENT7-01 ~]$ ls /tmp/test123*
/tmp/test123  /tmp/test1234  /tmp/test12345  /tmp/test123_2  /tmp/test123_3
[test@BS-PUB-CENT7-01 ~]$ !!:s/ls/echo/
echo /tmp/test123*
/tmp/test123 /tmp/test1234 /tmp/test12345 /tmp/test123_2 /tmp/test123_3
[test@BS-PUB-CENT7-01 ~]$  echo !ls:$:s/test/aaaa/
 echo /tmp/aaaa123*
/tmp/aaaa123*

直前に実行したコマンドであれば、以下のようにして文字列を置換して再実行させることもできる。

^置換前^置換後
[root@BS-PUB-CENT7-01 ~]# ls /tmp/test123 /tmp/test123_2 /tmp/test123_3
/tmp/test123  /tmp/test123_2  /tmp/test123_3
[root@BS-PUB-CENT7-01 ~]# ^ls^echo
echo /tmp/test123 /tmp/test123_2 /tmp/test123_3
/tmp/test123 /tmp/test123_2 /tmp/test123_3
[root@BS-PUB-CENT7-01 ~]# ^test^aaa
echo /tmp/aaa123 /tmp/test123_2 /tmp/test123_3
/tmp/aaa123 /tmp/test123_2 /tmp/test123_3

8.Ctrl + Rキーでhistoryの検索を行う

過去に実行したコマンドを検索したいなら、Ctrl + Rキーでキーワード検索が行える。
下の画像は「ls」までで検索したところ。最後にlsコマンドで実行した内容が候補として出力されている。このまま実行したければEnterキーを、続きを検索したければそのままCtrl + Rを入力し続けていけばよい。通り過ぎた場合にはCtrl + Sキーで戻ることができる。

結構入力が面倒な処理もあるけど、手が覚えてしまえば操作が楽になりそうだ。