シェルとは、Unix におけるユーザインターフェースを提供するプログラムのことだ。 ログインすると「%」と表示してくれる、あれである。 シェルはユーザの入力を受け付け、コマンドを読み取って実行する。 ひどく単純なプログラムに見えるが、実際には多種多様な機能を隠し持っている。
シェルのいいところは、気に入らなければ別のものと簡単に交換できるという点である。 FreeBSD の場合、標準でインストールされるシェルは sh と csh がある。 ports でインストールできるシェルには bash や tcsh、zsh などがある。 他に ksh などが有名だ。 これらのシェルは、コマンドを読み取り実行するという基本的な機能は同じだが、コマンドヒストリや環境変数の扱い方、シェルスクリプトの文法などが異なっている。 どれを使うかは好みの問題になってくるので、いくつか使ってみて決めるのがよいだろう。 ちなみに NetDaemon では、tcsh をベースに話を進めることにする。 というのも筆者が普段使っているのが tcsh だからだ。
最初に述べた通り、シェルはユーザの入力を受け付け、コマンドを読み取ってそれを実行する。 しかし実際にはそれ以上の処理を行ってくれている。 順番に紹介していこう。
ワイルドカードとは、特別な意味を持った文字のことで、様々な条件に合致するファイルを複数個指定したいときなどに威力を発揮する。 一般的なシェルで使えるワイルドカードは次の通りだ。
? | 任意の文字。 |
---|---|
* | 任意の文字列。最長一致する。 |
[...] | カッコ内の文字のうちのどれか1文字。 |
[^...] | カッコ内の文字以外の1文字。[...] の逆。 |
{...,...} | コンマで区切られた文字列のうちのどれか。 |
これらのワイルドカードの例と、一致するファイル名を挙げておこう。
a?c | abc、axc、a+c、など |
---|---|
*.c | .c で終わるファイル、abc.c、main.c など |
alpha* | alpha で始まるファイル、alphabet.txt など |
[abc]* | a、b、c のいずれかで始まるファイル、alfa、bravo、charlie など |
[^xyz]* | x、y、z のいずれかで始まらないファイル |
*.{doc,txt} | doc または txt で終わるファイル、foo.txt、bar.doc など |
このようなワイルドカードの展開は、コマンドが実行される前に行われる。 コマンドが引数を受け取るときには、すべてのワイルドカードは展開され、アルファベット順にソートされている。 このため、個々のコマンドがワイルドカードをサポートするという手間を省くことができる。
MS-DOS に馴染みのある人なら、ワイルドカードもご存じだと思う。 MS-DOS は Unix を真似ているが、すべてが完全に同じというわけではない。 ハマりそうな相違点を挙げておこう。
リダイレクトは、コマンドの出力先を変更する機能だ。 多くの Unix コマンドは、標準入力からデータを読み込み、標準出力へ処理結果を出力するよう設計されている。 特に指定しない場合、標準入力はキーボード、標準出力はディスプレイとなっている。 リダイレクトは、この標準入力、標準出力を任意のファイルへ切り替える機能なのだ。
たとえば echo コマンドは、コマンドラインに書いた文字列を、改行を付けて標準出力に出力している。 普通標準出力はディスプレイなので、結果として画面に表示されるのだ。 リダイレクトを使えば、これをファイルに向けることができる。
% echo Hell, World. Hell, World % echo Hell, World >foo % cat foo Hell, World
例のように、> に続いて指定するファイル名が出力先ファイルとなる。
リダイレクト関連のコマンドを一覧にしておこう。
>file | 標準出力をファイルへ切り替える。 |
---|---|
<file | 標準入力をファイルへ切り替える。 |
>>file | 標準出力をファイルへ切り替える。ファイルが存在していれば、出力結果は末尾に追加される。 |
<<string | ヒア・ドキュメント。ここから先、string という行が現れるまで標準入力が読み込まれ、その内容と置き換えられる。 |
`command ...` | コマンドを実行し、その出力結果と置き換える。 |
ヒア・ドキュメントはちょっと分かりづらいかもしれない。 コマンドラインよりは、シェルスクリプトで使うことが多いだろう。 `...` は、 たとえば「alpha という文字列を含むファイルをピックアップし、vi で編集したい」というときならこういう風に使える。
% vi `grep -l alpha *`
grep は -l オプションを指定すると、一致した行ではなくファイル名だけを表示する。 それが vi のコマンドラインへ展開され、vi が起動される。
パイプはリダイレクトに似ている。 パイプとは、あるコマンドの標準出力を別のコマンドの標準入力に連結する機能だ。 パイプを使うには、コマンド名の間に | を置くだけでよい。
たとえばディレクトリに何個のファイルがあるかを数えたければ、リストを表示する ls と、行数を数える wc を組み合わせればよい。
% ls Makefile ethernet.txt make.txt rc_conf.txt wuftpd.txt admin.txt fbsdinst.txt named.txt route.txt xntpd.txt apache.txt httpd_conf.txt netmask.txt routing.txt apacheinst.txt index.txt network.txt sendmail.txt daemon.txt inetd_conf.txt ntp.txt shell.txt database.txt ipaddress.txt permission.txt vi.txt % ls n* | wc -l 4
この例では、n で始まるファイルが何個あるのかを数えている。 答えは4個だ。
シェルは過去に実行したコマンドを覚えており、それらを簡単に呼び出す機能がある。 それがヒストリ機能だ。 古来コマンドヒストリは、直前のコマンドを繰り返すか、最初の数文字が一致するものを呼び出すが、具体的に起動番号を指定するかの原始的な方法しかなかった。 最近のシェルは、コマンドキー一発でヒストリをひとつずつ遡ることができるので大変便利だ。
!! | 直前のコマンドをもう一度実行する。 |
---|---|
!abc | abc で始まるコマンドラインをヒストリから探して実行する。もっとも最近に実行したコマンドが選ばれる。 |
!123 | ヒストリ内の番号で指定されたコマンドラインを実行する。 |
^P または ↑ | ヒストリを過去へ向かって遡る。 |
^N または ↓ | ヒストリを新しいものへ向かって戻る。 |
history | ヒストリリストを表示する。 |
環境変数はシェルが管理している変数で、シェルから起動されるコマンドも同様にこの変数を利用することができる。 身近な例でいけば、環境変数 PAGER にコマンドを設定しておくと、man コマンドを使うときのビューアとしてそのコマンドを使って表示してくれる。
環境変数はコマンドからの参照だけでなく、シェルスクリプトで使ったりコマンドラインで展開したりすることもできる。
環境変数の設定は、bourne シェル系と csh 系で大きく異なっている。 sh や bash では、値の設定は次のようにする。
$ PAGER=/usr/local/bin/jless $ export PAGER
sh では、export を実行しておかないと、シェルが起動するコマンドに対してその環境変数は渡されない。 一方 csh では、このようになる。
% setenv PAGER /usr/local/bin/jless
設定した環境変数は、$ を付けることで参照することができる。
% echo $PAGER /usr/local/bin/jless
シェルには、ワイルドカードや >、| など、特別な意味を持ったメタ文字が数多く存在する。 だがそれらの文字を、特別な意味なしに使いたいこともある。 また、コマンドラインではスペースは区切り文字としてコマンドに渡されてしまうので、スペースを含めてひとつのパターンにしたいときも困ってしまう。 そのようなメタ文字の意味を打ち消したいときに使えるのがエスケープと引用符だ。
\ | 直後の文字そのものを示す。\> はもはやリダイレクトではない。\ 自身は \\ と入力しないとだめ。 |
---|---|
"..." | ダブルクォート。この中では $ 以外のメタ文字の意味が打ち消される。$ だけは展開される(ダブルクォートは別)。 |
'...' | シングルクォート。この中では $ も含めてすべてのメタ文字の意味が打ち消される(シングルクォートは別)。 |