連載
» 2016年10月12日 05時00分 公開

Windows→Linuxクロスレファレンス:Bashのコマンド編集機能と履歴管理 (2/2)

[打越浩幸,デジタルアドバンテージ]
前のページへ 1|2       

viスタイルのキー操作でコマンドラインを編集する

 vi(もしくはvim)は、どのLinuxにもほぼデフォルトでインストールされていて、非常によく使われる軽量なエディタである(emacsは追加インストールしないと利用できないことが多い)。そのため、bashにもvi風にキー操作ができる編集スタイルが用意されている。

 ただしviは文字挿入モードやコマンドモード、カーソル移動モードなどを持つエディタなので、コマンドラインの編集にはやや使いづらい。そのためか、bashのデフォルトはemacsスタイルに設定されている。

 viスタイルを利用するには「set -o vi」を実行する(emacsスタイルに戻すには「set -o emacs」を実行する)。

user01@DESKTOP-5TV2I57:~$ set -o vi ……viスタイルに設定する
user01@DESKTOP-5TV2I57:~$



 このスタイルにするとvi風のキーバインドになるが、最初から[i]キーが押されていて、挿入モードが有効な状態になっている。挿入モードを終了してカーソル移動などを行いたければ、まず[Esc]キーを押してから操作すること。

 以下にviスタイルにおける主なキー割り当てをまとめておく。

キー 機能
[Esc] 挿入モードや変更、追加モードなどを終了する。現在のモードがよく分からなくなったら取りあえず[Esc]を押しておこう
[i] カーソル位置の前に挿入するモードに入る。挿入(や追加など)の終了は[Esc](以下同)
[a] カーソル位置の後ろに挿入(追加)するモードに入る
[I] 現在行の先頭に挿入するモードに入る
[A] 現在行の末尾に追加するモードに入る
[k]もしくは[-] 履歴を1つ前へ進める
[j]もしくは[+] 履歴を1つ次へ進める
[h] カーソルを1文字分左へ移動する
[l] カーソルを1文字分右へ移動する
[b] カーソルを1つ前の単語へ移動する(単語間の区切りは空白と記号文字とする)
[w] カーソルを1つ後の単語へ移動する
[e] カーソルを現在の単語の末尾へ移動する
[B] カーソルを1つ前の単語へ移動する(単語間の区切りは空白文字とする。以下同)
[W] カーソルを1つ後の単語へ移動する
[E] カーソルを現在の単語の末尾へ移動する
[0] カーソルを行頭へ移動する
[^] カーソルを行頭にある(空白以外の)文字へ移動する
[$] カーソルを行末へ移動する
[x] カーソルの位置の文字を1文字削除する
[X] カーソルの位置の直前の文字を1文字削除する
[p] 削除バッファの内容をカーソル位置に貼り付ける
[c]<移動> カーソル位置から指定した移動先までの文字を置換する。終了は[Esc]。<移動>には、[h]や[l]などの移動系コマンドを指定する(以下同)
[d]<移動> カーソル位置から指定した移動先までの文字を削除する
[D] カーソル位置から行末までを削除する。[d][$]と同じ
[r]<文字> カーソル位置の1文字を置換する
[R] カーソル位置から順次置換(上書き)する。終了は[Esc]
[C] カーソル位置から行末までを削除後、文字を追加するモードに入る。終了は[Esc]。[c][$]と同じ
[d][d] 行全体を削除する
[c][c] 行全体を削除してから挿入モードに入る
<数字>[G] 指定した番号のコマンド履歴を呼び出す
[~] カーソル位置の文字の英大文字←→英小文字を入れ替える
[.] 最後の削除や挿入、追加、置換などを繰り返す
[u] 最後の編集操作をアンドゥする
[U] 現在行に対する編集操作をすべてアンドゥして元に戻す
[/]<文字列> 指定した文字列を含むコマンド履歴行を探す
[?]<文字列> 指定した文字列を含むコマンド履歴行を、逆方向に探す
viスタイルの場合に利用可能なキー割り当て(主要なもののみ)
viはいちいち挿入モードにしないと文字入力ができないなど、モード切り替えがやや面倒である。その代わり、通常の英記号キーなどをほとんど全てコマンドに割り当てることができるため、例えばカーソル移動機能などはとても豊富である。

bashのhistory(ヒストリ)機能を使う

 bashのコマンド履歴機能は、もともとはcshに実装されていたhistory機能に由来している。この機能を使うと「!」修飾子を使って履歴を呼び出したり、編集・再実行したりできる。

 履歴の一覧を表示させるには「history」コマンドを実行する。すると、今までに実行したコマンドの一覧が番号付きで表示される。

user01@DESKTOP-5TV2I57:~$ help history
history: history [-c] [-d offset] [n] または history -anrw [filename] または history -ps arg [arg...]
    ヒストリ一覧を表示または操作します。

    行番号をつけてヒストリを表示します。操作した各項目には前に`*'が付きます。
    引数 N がある場合は最後の N 個の項目のみを表示します。

    オプション:
      -c        ヒストリ一覧から全ての項目を削除します。
      -d offset OFFSET 番目のヒストリ項目を削除します。

      -a        このセッションからヒストリファイルに行を追加します
      -n        ヒストリファイルからまだ読み込まれていない行を全て読み込みます
      -r        ヒストリファイルを読み込み、内容をヒストリ一覧に追加します
      -w        現在のヒストリをヒストリファイルに書き込みます。そしてそれらを
        ヒストリ一覧に追加します
……(以下省略)……
user01@DESKTOP-5TV2I57:~$ history
    1  set
    2  set -o
    3  h
    4  history
    5  echoo hello world
    6  echo hello world
    7  set -o vi
……(以下省略)……



 直前に実行したコマンドをそのまま再実行するには「!!」([↑]キーを押して[Enter]するのと同じ)、特定の番号のコマンドを再実行するには「!123」のようにコマンド履歴の番号を指定すればよい。呼び出されて実行されたコマンドは、また履歴の最後に追加される。

 指定したコマンド履歴を再実行するのではなく、単に履歴リストの最後に追加するだけなら「!!:p」のようにする。こうすると!!でまたすぐに呼び出せるし、再編集する場合も便利である。直前のコマンドなら[↑]キー1回で呼び出せるし、「^hello^Hello」のような置換機能も使えるからだ。

 以下にhistory機能で利用可能なコマンド履歴の指定方法を示しておく。

コマンド指定 機能
!! 直前のコマンド
!<数字> 指定した番号のコマンド
!-<数字> 指定した数だけ前のコマンド(例:「!-10」なら10個前のコマンド
!<文字列> 指定した文字列で始まる、最も新しいコマンド
!?<文字列>? 指定した文字列を含む、最も新しいコマンド
^<文字列1>^<文字列2>^ 直前のコマンド中の<文字列1><文字列2>に置換する
!記号による主なコマンド履歴の指定方法

 以上のような方法でコマンド履歴を参照し、さらに次のような置換指定や修飾子を付けることによって、コマンド列の一部を修正したり、コマンド履歴中の引数を使って新しいコマンドを合成したりできる。

コマンド指定 機能
■置換指定  
:0 コマンド名(コマンド列の先頭)
:1 :2 :3 …… コマンドの第1引数、第2引数、第3引数、……
^ 最初の引数(第1引数)
$ 最後の引数
:<数字1>-<数字2> 指定した番号範囲の全引数
* 全引数
■履歴修飾子  
:p 表示のみで、実行しない
:s/<文字列1><文字列2>/ <文字列1><文字列2>に置換する(初出だけ)
:gs/<文字列1><文字列2>/ <文字列1><文字列2>に置換する(全部)
:r フルパス名から拡張子を除いた部分
:e フルパス名に含まれる拡張子部分だけ
:h フルパス名のフォルダ名部分だけ
:t フルパス名中の最後のファイル名と拡張子の部分だけ
:記号による主なコマンド履歴の修飾方法

 以下のコマンド履歴の編集例を示しておく。

user01@DESKTOP-5TV2I57:~$ echoo Hello, world.   ……間違ったコマンドを入力してみる
コマンド 'echoo' は見つかりませんでした。もしかして:  ……エラー
 コマンド 'echo' - パッケージ 'coreutils' (main)
echoo: コマンドが見つかりません
user01@DESKTOP-5TV2I57:~$ ^echoo^echo^:p  ……コマンド名を修正するが、:pで実行を抑止する
echo Hello, world.  ……修正後のコマンドが表示されているが、実行はされていない
user01@DESKTOP-5TV2I57:~$ ^Hello^Hi  ……もう1カ所修正して実行してみる
echo Hi, world.  ……修正後のコマンド
Hi, world.  ……実行結果
user01@DESKTOP-5TV2I57:~$
user01@DESKTOP-5TV2I57:~$ vi prj/test.c  ……ファイルを編集してみる
user01@DESKTOP-5TV2I57:~$ cat -n !*  ……同じ引数で別のコマンドを実行してみる
cat -n prj/test.c  ……実行するコマンド
     1  #include <stdio.h>  ……結果(行番号付きのプログラムリストの表示)
     2  int main()
     3  {
     4    printf("Hello, world\n");
     5  }
     6
user01@DESKTOP-5TV2I57:~$ gcc !$  ……ファイル名を引数にしてコンパイラを起動してみる
gcc prj/test.c  ……実行するコマンド
user01@DESKTOP-5TV2I57:~$ ./a.out  ……実行してみる
Hello, world  ……実行結果
user01@DESKTOP-5TV2I57:~$ h  ……コマンド履歴を確認してみる
h: コマンドが見つかりません  ……hという名前のコマンドはない
user01@DESKTOP-5TV2I57:~$ alias h=history  ……よく使うので「h」と言う名前のエイリアス(コマンドの別名)を定義しておく
user01@DESKTOP-5TV2I57:~$ h  ……もう1度実行してみる
    1  set -o  ……結果
    2  h
    3  history
    4  cls
    5  clear
    6  set -o emacs
    7  ls
    8  ls -a
    9  cd /tmp
   10  printenv
   11  help set
……(以下省略)……



コマンド履歴の管理

 コマンド履歴に記録されているコマンド列は、bashの終了時にユーザーのホームディレクトリにある~/.bash_historyファイルなどに保存される。コマンド履歴を幾つ保存するか、どのファイルに保存するかなどは、HISTOFILEやHISTFILESIZE変数などにセットされている。

user01@DESKTOP-5TV2I57:~$ set | grep HIST ……履歴関連の変数を確認する
HISTCONTROL=ignoreboth
HISTFILE=/home/user01/.bash_history ……履歴を保存するファイル
HISTFILESIZE=2000 ……履歴を保存するファイルのサイズ
HISTSIZE=1000 ……保存するコマンド履歴の数
user01@DESKTOP-5TV2I57:~$




 今回はbashを使う上で基本となるコマンドラインの編集方法や履歴の利用方法について見てきた。CUIやLinuxなどを使うというなら、bashの操作は避けて通れないだろう。ぜひ覚えていただきたい。次回からはbash(Linux)の基本的な使い方について解説する。

「Windows→Linuxクロスレファレンス」のインデックス

Windows→Linuxクロスレファレンス

前のページへ 1|2       

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。