bashの便利な機能を使いこなそう

第9回 bashの便利な機能を使いこなそう

「シェル」。人とOS(カーネル)をつなぐもの。シェルの使い勝手はOSの使い勝手とほぼ同義である。bashの機能を使いこなせば、Linuxはさらに使いやすく、快適になるだろう。そこで、操作をサポートする機能の使い方やbashのカスタマイズ方法を紹介する。

関野史朗
2002/3/12

コマンドに別の名前を付けて使いやすく

 まず最初に紹介するのは、「エイリアス」(alias:別名)です。文字どおり、コマンドに別名を付ける機能です。

 例えば、日本語化されたlsがあって、jlsという名前だとしましょう。いちいち「jls」とタイプするのは面倒なので、「ls」とタイプするだけでjlsを実行するようにしたい場合などに利用します。具体的な方法は、

$ alias ls=jls

です。これで、「ls」とタイプするとjlsが実行されます。ただし、エイリアスが効くのはコマンドラインからタイプしたときだけで、シェルスクリプト中ではlsはlsのままです。

 引数の付いたコマンドを実行させたい場合は、「'」(シングルクオート)でくくります。Emacs上で動作するMUA「mew」は、Emacsから実行することもできますが、

$ emacs -e mew

として直接コマンドラインから実行することも可能です。このエイリアスを作る場合は、

$ alias mew='emacs -e mew'

とします。

 シェルスクリプトでもエイリアスと同じことを実現できます。ただ、シェルスクリプトだとコマンドごとに独立したファイルを作らざるを得ません(工夫によって、いくつかを統合できますが)。作成したスクリプトは、コマンドパスに指定されたディレクトリに格納しておく必要があります。単純なコマンドの置き換えだったらエイリアスの方が手軽ですね。

ファイル名補完でタイプの手間とミスを減らす

 bashを使っていて何がありがたいかといえば、「ファイル名補完」でタイプの手間が省けることでしょう。[Tab]キーを押すと、bashが残りの文字列を入力してくれるのです(編注)。

編注:ちなみに、Windows NT/2000のコマンドプロンプト(cmd.exe)にもファイル名補完機能がある(レジストリの編集が必要)。HKEY_CURRENT_USER\Software\Microsoft\Command Processor\CompletionCharのDWORD値を9(デフォルトは0)にして再起動すればよい。bashと同じく[Tab]キーでファイル名を補完するようになる。Windows XPはデフォルトで補完機能が有効になっているので、レジストリの編集は不要だ。

 補完機能を理解するには、試してみるのが一番です。取りあえず、「le」とタイプしてから[Tab]キーを2回押してみましょう。

$ le
leaftoppm    lessecho     lesspipe.sh  lex
less         lesskey      let
$ le

と表示されます。これが「le」で始まるコマンドです。続けて「a」とタイプして、もう1度[Tab]キーを押します。すると今度は一覧表示が出ず、コマンドライン上に

$ leaftoppm

と表示されます。「lea」までタイプすると、これで始まるコマンドは1つしかないので対象が確定するわけです。

 コマンドだけでなく、引数も補完できます。例えば、/etcディレクトリで、

$ less c[Tab]キー

とすると、

cdrecord.conf  cron.d         cron.hourly    cron.weekly    csh.cshrc
cipe           cron.daily     cron.monthly   crontab        csh.login
$ less c

と表示されます。続けて「r」をタイプして[Tab]キーを押すと、今度は一覧表示ではなく、

$ less cron

というコマンドラインが表示されます。この状態でさらに続けて2度[Tab]キーを押すと、cronで始まるファイルの一覧が、

cron.d        cron.hourly   cron.weekly
cron.daily    cron.monthly  crontab

のように表示されます。コマンドラインは変わっていないので、もう1文字「t」をタイプしてから[Tab]キーを押せば、

$ less crontab

となります。「cront」で始まるファイルは1つしかないので、ファイル名はこれで確定です。よく見ると、crontabの後ろに空白があるのでそれと分かります。これで、[Enter]キーを押すとcrontabファイルの中身を表示できるというわけです。

 ファイル名補完を使うと、タイプの手間を大幅に減らせます。さらに、タイプミスも少なくなるというおまけ付きです。どんどん活用しましょう。

ワイルドカードで複数ファイルを一括指定

 複数のファイルに対して同じ処理を行う際に便利なのが、「ワイルドカード」です。MS-DOSやWindowsでもおなじみの、「*」や「?」です。「*」は任意の文字列、「?」は任意の1文字を表します。「*.txt」なら拡張子がtxtのファイルすべて、「cron*」なら名前が「cron」で始まるファイルです。「*rom*」とすると、途中に「rom」という文字列を含むファイルということになります。

 正規表現の一部である「クラス表現」も使えます。クラス表現とは、「[a-z]」のような表記です。これで小文字のアルファベット「aからz」までのいずれか1文字にマッチします。否定の「!」を使って「[!a-z]」とすると、「aからz以外」の1文字にマッチすることになります。「test.[co]」なら、test.cとtest.oを意味するわけです。

 ワイルドカードを展開するのはbashの仕事で、コマンドには展開された結果である複数のファイル名が引数として渡されます。つまり、コマンド側でワイルドカードを展開する必要はない、ということです。なお、「*」などの文字をワイルドカードとして展開してほしくないときは、シングルクオートでくくります。

過去に入力したコマンドを実行する

 以前入力したのとまったく同じ、あるいは引数だけ違うコマンドを再実行することはよくあります。これを簡単に行えるのが「ヒストリ機能」です。

$ history

とすると、過去に実行したコマンドがリストされます。それぞれに数字が付いているので、「!」に続けて実行したいコマンドの数字をタイプし、[Enter]キーを押すとそのコマンドを再実行できます。また、「!」に続けて文字をタイプすると、その文字で始まる過去のコマンドが実行されます。

 この辺りは、いにしえのテレタイプベースでの動作を前提とした機能です。もちろん、bashにはビデオ端末に即したヒストリ機能もあります。まず[Ctrl]+[P](あるいは[↑]キー)を押すと、過去に入力したコマンドを順番にさかのぼって表示します。行き過ぎたら、[Ctrl]+[N](あるいは[↓]キー)で戻れます。目的のコマンドが表示されたら、[Enter]キーで実行です。

 コマンドをそのまま実行せず、引数などを変更したい場合は、Emacsに準じたキーの組み合わせで編集できます。単純にカーソルを1つずつ動かすだけなら、カーソルキーも使えます。

  行頭に移動 [Ctrl]+[A]
  行末に移動 [Ctrl]+[E]
  1文字左に移動 [Ctrl]+[B]
  1文字右に移動 [Ctrl]+[F]
  1単語左に移動 [ESC]+[B]
  1単語右に移動 [ESC]+[F]
  1文字削除 [Ctrl]+[D]、[Ctrl]+[H]

 察しのよい方はお気付きかもしれませんが、インクリメンタルサーチもできます。[Ctrl]+[R]でこのモードに入ります。適当に文字をタイプすると、その文字を含んだ過去のコマンドが表示されます。複数の文字をタイプすれば、その順番で入力された過去のコマンドを表示します。

bashのカスタマイズ

 bashは、組み込みの「シェル変数」を使ってその動作をある程度変更できます。シェル変数の設定方法は、

$ HISTSIZE=100

のように、変数名に数値あるいは文字列を代入する形になります。
 組み込み変数にどんなものがあるか、ざっと見てみましょう。

ヒストリ関係

HISTCMD
 現在のコマンドのヒストリ番号。

HISTCONTROL
 ignorespace:スペースやタブで始まる行をヒストリに記録しない
 ignoredups:入力が最後のヒストリと一致する場合に記録しない
 ignoreboth:ignorespaceとignoredups両方を指定
 指定なし:すべての入力をヒストリに記録する

HISTFILE
 ヒストリファイル名。
 例:HISTFILE=/home/username/.bash_history

HISTFILESIZE
 ヒストリファイルに格納するヒストリの最大数。

HISTSIZE
 ヒストリとして記録されるコマンドの最大数。HISTSIZEの値を小さくした場合、過去のヒストリは切り捨てられる。例えば、値を100から50に変更すると、残るのは最近の50行までとなる。

メール関係

MAIL
 メールの到着を確認する対象となるべきファイルの名前。
 例:MAIL="/var/spool/mail/$USER"

MAILCHECK
 メールをチェックする間隔。単位は秒。

MAILPATH
 メールの到着を確認する対象となるべきファイルの名前。複数のファイル名を「:」(コロン)で区切って指定できる。
 例:MAILPATH='/var/mail/bfox?"You have mail":~/shell-mail?"$_ has mail!"'

プロンプト関係

PS1
 通常のプロンプト。いくつかの特殊文字が使える。

 
特殊文字
意味
  \d 日付
  \h ホスト名
  \n 改行
  \s シェルの名前
  \t 時間
  \u ユーザー名
  \w ワークディレクトリ
  \W ワークディレクトリのベース名
  \# コマンド番号
  \! ヒストリ番号
  \$ 有効なUIDが0なら「#」、それ以外なら「$」
  \nnn 8進数での文字コード
  \\ バックスラッシュそのもの
  \[ 非表示文字の開始
  \] 非表示文字の終了

 例:以下、「PS1=xxx」が入力部分。

$ PS1="\d "
Wed Mar 6 PS1="\h "
sun PS1="\s "
bash PS1="\t "
02:27:39 PS1="\u "
tom-a PS1="\w "
~ PS1="\W "
tom-a PS1="\# "
27 PS1="\! "
37 PS1="\u@\h\$ "
tom-a@sun$

PS2
 継続行に表示されるプロンプト(セカンダリプロンプト)。forコマンドでdo〜doneの部分を入力するときなどに使われる。

パス関係

PATH
 コマンド検索パス。「:」で区切った複数のパス名を記述する。

CDPATH
 cdコマンドに対する候補を「:」で区切って複数記述する。

そのほか参照用

HOME
 ホームディレクトリ。

SECONDS
 シェルが呼び出されてからの秒数。

BASH
 起動しているシェルの実行可能ファイルへのパス名。

BASH_VERSION
 起動しているbashのバージョン番号。

PWD
 カレントディレクトリ。

OLDPATH
 cdコマンド実行前のディレクトリ。

bashの設定ファイル

 これらのシェル変数をいちいちタイプして設定するのは面倒です。そこで、普通は~/.bashrcや~/.bash_profileといったファイルに書き込んでおきます(編注)。

編注:以下に見るように、/etc/profileが最初に読み込まれるファイルだが、このファイルの内容は全ユーザーに適用されるため、一般ユーザーが変更することはできない。ユーザーごとの設定は、ホームディレクトリのドットファイルを使用する。

ログイン時に読み込まれる設定ファイル

 bashの関連ファイルには、次のようなものがあります。

 ユーザーがログインすると、まず/etc/profileを読み込み、次に~/.bash_profileを読み込みます。~/.bash_profileが存在しない場合は、~/.bash_loginを読み込みます。~/.bash_loginもない場合は~/.profileを読み込みます。~/.bash_logoutは、ログアウト時に読み込まれるファイルです。

 .bashrcは、プロセスとしてbashを起動したときに読み込まれます。つまり、いったんログインした後でも、

$ bash

などとして新しくbashを起動するたびに読み込まれるというわけです。

 どれも単なるテキストファイルですから、エディタで簡単に編集できます。しかし、編集しただけでは変更が反映されません。いったんログアウトしてもう1度ログインし直すか、sourceコマンドを使って、

$ source .bash_profile

$ source .bashrc

とする必要があります。

 .bash_profileと.bashrcの使い分けですが、ログイン時に一度設定すればいいものは前者に、bashを起動するたびに設定する必要のあるものは後者にするのが原則です。もっとも、私の場合はどちらも同じなので、.bash_profileの内容は

source .bashrc

という1行しかありません。