Last Update 2022/09/22
履歴(ヒストリ)
(01)
シェル変数 HISTFILE、HISTSIZE、HISTFILESIZE
$ echo $HISTFILE
/home/testusr/.bash_history <--- 履歴リストファイル
$ echo $HISTSIZE
1000 <--- 履歴リスト最大数
$ echo $HISTFILESIZE
1000 <--- 履歴リストファイル最大数
$ cp -v .bash_history sample_history <--- 履歴ファイルをテスト用にコピー
'.bash_history' -> 'sample_history'
$ ls -l sample_history
-rw------- 1 testusr testusr 8372 Sep 18 15:37 sample_history <--- テスト用ファイルサイズ
$ HISTFILE='/home/testusr/sample_history' <--- HISTFILEにsample_historyを指定
$ HISTFILESIZE=5 <--- HISTFILESIZEに5を設定
$ ls -l sample_history
-rw------- 1 testusr testusr 60 Sep 18 15:45 sample_history <--- ファイルサイズが60に縮小
$ cat sample_history
ls -l
echo $HISTSIZE
echo $HISTFILESIZE
echo $HISTIGNORE
su <--- 履歴リストファイルが5行に切り詰められる
$ history <--- 現状の履歴リストを確認
1 ls -l
2 cd
︙
600 cat sample_history
601 history
$ HISTSIZE=5 <--- HISTSIZEに5を設定
$ history
598 ls -l sample_history
599 cat sample_history
600 history
601 HISTSIZE=5
602 history <--- 履歴リストに格納されるコマンド数が5個となる
$
(02)
イベント指示子
!コマンド番号
[コマンド番号]を参照
$ history <--- 履歴リスト中のコマンド番号の確認
1 echo "command1"
2 echo "command2"
3 echo "command3"
4 history
$ !2 <--- コマンド2を参照
echo "command2" <--- コマンド2を実行
command2
$
!-減算値
現在のコマンド番号 - [減算値] のコマンドを参照
$ history <--- 履歴リスト中のコマンド番号の確認
1 echo "command1"
2 echo "command2"
3 echo "command3"
4 history
$ !-3 <--- コマンド(5-3)を参照
echo "command2" <--- コマンド2を実行
command2
$
!!
現在のコマンドから一つ前のコマンドを参照
$ history <--- 履歴リスト中のコマンド番号の確認
1 echo "command1"
2 echo "command2"
3 echo "command3"
4 history
$ !! <--- 一つ前のコマンドを参照
history <--- 直前のコマンド4を実行
1 echo "command1"
2 echo "command2"
3 echo "command3"
4 history
$
!文字列
[文字列]で始まる履歴リスト中で一番最近実行したコマンドを参照
$ history <--- 履歴リスト中のコマンド番号の確認
1 echo "command1"
2 echo "command2"
3 echo "command3"
4 history
$ !echo <--- 「echo」で始まる履歴リスト中で一番最近実行したコマンドを参照
echo "command3" <--- コマンド3を実行
command3
$
!?文字列[?]
[文字列]を含む履歴リスト中で一番最近実行したコマンドを参照
$ history <--- 履歴リスト中のコマンド番号の確認
1 echo "command1"
2 echo "command2"
3 echo "command3"
4 history
$ !?command? <--- 「echo」を含む履歴リスト中で一番最近実行したコマンドを参照
echo "command3" <--- コマンド3を実行
command3
$
^文字列1^文字列2^
[文字列1]を[文字列2]に置換して直前のコマンドを実行
$ echo "command1"
command1
$ ^command1^command2^ <--- 直前のコマンドの「command1」を「command2」に置換して実行
echo "command2" <--- 置換の結果実行されるコマンド
command2
$
!#
これまでに入力されたコマンドライン全体を参照
$ ls -l
total 12
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample1.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample2.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample3.txt
$ cat sample1.txt !#:$:s/1/2/ !#:$:s/2/3/ <--- 「!#」が「$」を付けることで入力されたコマンドラインの最後の単語を参照することとなる
cat sample1.txt sample2.txt sample3.txt <--- 置換の結果実行されるコマンド
abc
def
ghi
$
(03)
単語指示子
0
ゼロ番目の単語
$ cat sample1.txt
abc
$ !!:0 sample2.txt <--- 直前のコマンドの0番目の単語「cat」を展開
cat sample2.txt
def
$
数値
[数値]番目の単語(0から始まる)
$ cat sample1.txt sample2.txt
abc
def
$ cat !!:2 <--- 直前のコマンドの2番目の単語「sample2.txt」を展開
cat sample2.txt
def
$
^
コマンドの最初の引数
$ cat sample1.txt sample2.txt
abc
def
$ cat !!:^ <--- 直前のコマンドの最初の引数「sample1.txt」を展開
cat sample1.txt
abc
$
$
最後の単語
$ cat sample1.txt sample2.txt
abc
def
$ cat !!:$ <--- 直前のコマンドの最初の単語「sample2.txt」を展開
cat sample2.txt
def
$
数値1-数値2
単語の範囲([数値1]~[数値2])
$ cat sample1.txt sample2.txt sample3.txt
abc
def
ghi
$ cat !!:1-2 <--- 直前のコマンドの1~2番目の単語を展開
cat sample1.txt sample2.txt
abc
def
$
*
0番目を除く全ての単語
$ cat sample1.txt sample2.txt sample3.txt
abc
def
ghi
$ ls -l !!:* <--- 直前のコマンドの0番目を除く全ての単語を展開
ls -l sample1.txt sample2.txt sample3.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample1.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample2.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample3.txt
$
数値*
[数値]-$の略記
$ ls -l sample1.txt sample2.txt sample3.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample1.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample2.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample3.txt
$ cat !!:2* <--- 直前のコマンドの2番目以降の全ての単語を展開
cat sample1.txt sample2.txt sample3.txt
abc
def
ghi
$
数値-
[数値]-$から最後の単語を省略
$ ls -l sample1.txt sample2.txt sample3.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample1.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample2.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample3.txt
$ cat !!:2- <--- 直前のコマンドの最後を除く2番目以降の全ての単語を展開
cat sample1.txt sample2.txt
abc
def
$
(04)
修飾子
h
パス名末尾のファイル名を削除
$ cat /home/testusr/sample1.txt
abc
$ ls -l !!:$:h <--- 直前のコマンドの最後の単語のパス名末尾のファイル名を削除
ls -l /home/testusr
total 12
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample1.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample2.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample3.txt
$
t
パス名からファイル名より前(ディレクトリ)を削除
$ cat /home/testusr/sample1.txt
abc
$ ls -l !!:$:t <--- 直前のコマンドの最後の単語のパス名から、ファイル名より前(ディレクトリ)を削除
ls -l sample1.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample1.txt
$
r
ファイル名から拡張子を削除
$ cat sample1.txt
abc
$ echo !!:$:r <--- 直前のコマンドの最後の単語のファイル名から拡張子を削除
echo sample1
sample1
$
e
拡張子以外を削除
$ cat /home/testusr/sample1.txt
abc
$ ls -l *!!:$:e <--- 直前のコマンドの最後の単語から拡張子以外を削除
ls -l *.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample1.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample2.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample3.txt
$
p
新しいコマンドを表示するが実行しない
$ cat /home/testusr/sample1.txt
abc
$ ls -l *!!:$:e:p
ls -l *.txt <--- 新しいコマンドを表示するのみ
$
q
置換された単語をクォートする
$ sample1="abc"
$ sample2="def"
$ sample3="ghi"
$ echo $sample1 $sample2 $sample3
abc def ghi
$ echo !!:* <--- クォート無し
echo $sample1 $sample2 $sample3
abc def ghi <--- クォート無しの場合のechoでの出力
$ echo !!:*:q <--- クォート有り
echo '$sample1 $sample2 $sample3' <--- 全体をまとめてクォート
$sample1 $sample2 $sample3 <--- クォート有りの場合のechoでの出力
$
x
置換された単語を空白、改行で分割後それぞれクォートする
$ sample1="abc"
$ sample2="def"
$ sample3="ghi"
$ echo $sample1 $sample2 $sample3
abc def ghi
$ echo !!:* <--- クォート無し
echo $sample1 $sample2 $sample3
abc def ghi <--- クォート無しの場合のechoでの出力
$ echo !!:*:x <--- クォート有り(空白、改行で分割)
echo '$sample1' '$sample2' '$sample3' <--- 空白、改行で分割後クォート
$sample1 $sample2 $sample3 <--- echoでの出力
$
s/数値1/数値2/
[数値1]を[数値2]に置換
$ ls -l sample1.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample1.txt
$ cat !!:$ !!:$:s/1/2/ !!:$:s/1/3/ <--- 直前のコマンドの最後の単語の数値部分を置換
cat sample1.txt sample2.txt sample3.txt
abc
def
ghi
$
&
前の置換を繰り返す
$ sample1="abc"
$ sample2="def"
$ sample3="ghi"
$ echo $sample1 $sample2 $sample3
abc def ghi
$ cat !!:1:s/$//.txt !!:2:&.txt !!:3:&.txt <--- 2番目以降の置換は最初の置換を繰り返す
cat sample1.txt sample2.txt sample3.txt
abc
def
ghi
$
g
イベント行全体に置換を適用
$ cat sample1.txt sample2.txt sample3.txt
abc
def
ghi
$ echo !!:*:gs/sample/$sample/:gs/.txt// <--- 2つの置換をイベントライン全体に適用
echo $sample1 $sample2 $sample3
abc def ghi
$
実行環境
GNU bash, version 5.1.16
GCC-8.2.0
GNU C Library 2.28
GNU Binutils 2.31.1
GCC-8.2.0
GNU C Library 2.28
GNU Binutils 2.31.1
コード例・出力内容中の表記
・実行例中の太字表記部分は、コマンドなどの入力された文字列を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。