最低限 UNIX / Linux [II]

# 最低限 UNIX / Linux [II]

実習の前準備
ファイルとディレクトリ
ファイルモードとリンクについて
シェル

## 4. シェル

### [4.1] シェル (Shell) とは

シェルとは、ユーザーから入力されたコマンドを解釈し、
プログラムを起動するアプリケーションです。
他の OS で機能的に似た役割を持つものとして、
Windows95/98では Explorer、Macintosh（MAC）では finder があります。
しかし、イメージとしては Windows95/98 の DOS プロンプトや、
WindowsNT のコマンドプロンプトの方が近いでしょう。

通常、シェルは login シェルとして、各ユーザがログインする度に起動され、
ログアウトの際に終了します。ログインすると、端末の上に、例えば
"samson$" と表示されますが、これがシェルが発している「プロンプト」（ユー
ザへコマンドの入力を促す記号）です。尚, kterm 等のターミナルを新たに立ち上
げると別のシェルが起動されます。

UNIX の内部構造をみると、核となる部分はカーネル（Kernel）と呼ばれ、
マルチタスクやファイルシステム、仮想記憶、入出力など、
OS にとって重要な機能を司っています。
ユーザーはカーネルを直接操るのではなく、
あらかじめ用意されたインターフェイス（窓口）を通して、
カーネルに対してコマンドの実行を要求します。
このインターフェイスの部分がシェルであり、
つまりシェルはユーザとカーネルの仲立ちをしているプログラムであると言えるでしょう。

シェルは Kterm 等のターミナル上で実行しますので、ターミナルを立ち上げないと
シェルというカーネルに対する窓口が使えません。
最近の Window manager は賢くなって X 上に色々なアイコンを表示してくれ、
それをクリックすると netscape 等が起動するようになっています。
しかし正しい作法はターミナルを立ち上げ、そこのシェルを通じて様々な
プログラムを起動することです。

### [4.2] シェルの役割

シェルには大きく分けて３つの役割があります。

ユーザーインターフェース（コマンド・インタプリタとしてのシェル）

プロンプトの表示
コマンドの読み込み
コマンドの前処理(解釈)
コマンドの実行

環境設定の道具
プログラミング言語（スクリプトを解釈する論理的な制御機能としてのシェル）

### [4.3] 代表的なシェルの紹介

主要なシェルには以下のようなものがあります。

sh（Bourne shell）：
現在利用できるもっとも古いシェル。
AT&T のベル研究所で開発され、
開発者の１人であるSteven Bourne 氏にちなんで名付けられた。
色々なシェルの中で共通項的な位置にあり、
ほとんど全ての UNIX で利用できる標準的なシェルであるため、
シェルスクリプトの作成には B シェルがよく用いられる。
csh（c shell）：
カリフォルニア大学バークレイ校の William Joy 氏が中心になって開発したシェルで、
C 言語に似た構文を持つことから、この名前が付けられている。
B シェルに比べ、ヒストリー機能やジョブ制御、
エイリアスなどの機能が付加されており、対話形式で使用する場合に便利である。
bash（Bourne Again shell）：
MIT（マサチューセッツ工科大学）の Brian Fox 氏が作成したシェルで、
現在、GNU ソフトウェアの一部として配布されている。
bash は、元来 B シェル において貧弱であった、
ユーザーインターフェイスとしての機能を強化するため、
ヒストリー機能、エイリアスなどが追加されている。
その他：
csh の拡張版である tcsh（TC shell）や、zsh、ksh などがあります。

### [4.4] 利用するシェルの確認と変更

#### [4.4.1] 現在、自分がどのシェルを使っているか調べる方法

$ set

$ finger username

#### [4.4.2] 自分のログインシェルの変更方法

$ chsh （または ypchsh）

次にログインするときに、変更したシェルが起動されます。
（管理者の設定により無理な場合があります）

### [4.5] bash の機能

#### [4.5.1] シェルの組み込みコマンド

多くのシェルは、ls や kterm などの独立したコマンドを実行するだけでなく、
あらかじめシェルのプログラムに組み込まれているコマンドを幾つか持っています。
このようなコマンドは"組み込みコマンド"と呼ばれ、以下のようなものがあります。

echo, set, unset, alias, history, cd, ...

help コマンドを利用すると、これら組み込みコマンドの、簡単な説明を得られます。

（help で説明可能な）組み込みコマンドの一覧を表示：

- $ help
- 組み込みコマンドの説明を表示：
- $ help [コマンド名]

#### [4.5.2] シェル変数

bashは、シェル自身の動作を定義する変数を持っています。
この、シェルが内部で保持している変数を、"シェル変数"と言います。
シェルスクリプトや、コマンドの入力の際に、
値を一時的に格納して後で再利用できるようにするための変数でもあります。
後述する環境変数と違い、シェル以外のプログラムからは参照できません。

基本的に、変数名をつける際は、好きなようにつけて構わないのですが、すでに定義され
ている変数とは重ならないように指定した方が無難です。

現在設定されているシェル変数を見るには、set と打ち込みます。
シェル変数の設定と変更は、"＝"を使います。(シェル変数名＝シェル変数の値)
シェル変数の値を調べるには、echo $変数名 と打ち込みます。
シェル変数の削除は、unset コマンドを使います。(unset シェル変数名)

例として、プロンプトの表示を変えてみましょう。
プロンプトの表示は、シェル変数"PS1"を用いて設定することが出来ます。

$ PS1="\u% "
inex%
inex% PS1="\d$ "
Fri Nov 26$
Fri Nov 26$ PS1="\s-\v\$ "
bash-2.01$

#### [4.5.3] 環境変数

シェル変数はシェルの中だけで使われる変数ですが、
こちらは、アプリケーションやコマンドなどの動作を統一的に制御するために
、ユーザーが設定する変数です。

有名な環境変数

環境変数名 意味
USER ユーザ名
HOST ホスト名
LANG 言語環境。日本語ならば ja_JP.ujis、英語ならば C。
PATH コマンドサーチパス。
HOME ホームディレクトリ。

現在設定されている環境変数を見るには、printenv と打ち込みます。
環境変数の設定と変更は、export コマンドを使います。
シェル変数の値を調べるには、printenv 変数名と打ち込みます。

シェル変数・環境変数には、
あらかじめ使い方が決められたものがあり、
変更には注意が必要です。

例として、以下の４つのコマンドを順番に入力してみてください。

$ export LANG=C
$ man man
$ export LANG=ja_JP.ujis
$ man man

これを実際に試してみると、
一度目の man man と二度目の man man で出力される結果が違うのが、
確認できると思います。
環境変数とはこのように、
あらかじめ設定していた文字列によってプログラムの動作を規定する為のものです。
（プログラム側で対応していない場合は効果ありません）

次に以下のコマンドを実行して下さい。

$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:
$ pwd
/home/hogehoge
$ export PATH=""
$ pwd
bash: pwd: command not found
$ /bin/pwd
/home/hogehoge

< 環境変数 PATH を表示させます
> hogehoge さんのホームディレクトリに居ます.
< 環境変数 PATH を空にします.
> pwd コマンドは無いと言われました.
< pwd コマンドの絶対パスを指定しました.
> hogehoge さんのホームディレクトリに居ます.

すると最初は存在していたはずの pwd コマンドが存在しないと言われるでしょう.
コマンドもファイルですから本来は絶対パスで書かねばならないのですが,
PATH 環境変数にコマンドの置かれているディレクトリを指定しておくと
コマンド名そのもので実行できます.

#### [4.5.4] メタキャラクタ（ワイルドカード）

コマンド入力の際に、
複数のファイル名を「ある規則にしたがってまとめて表す」という試みのために用いられる文字のことを、
"メタキャラクタ"（ワイルドカード）と言います。
メタキャラクタを用いると、タイプする文字数を減らすことができるので、
効率的に入力が行えます。

代表的なメタキャラクタ

メタキャラクタ 意味
* 任意の文字列を表す。
? 任意の１文字を表す。?? は任意の２文字になる。
[ ]
[ ] 内に含まれる文字にマッチする。
例えば [a-c]* は abc のいすれかで始まる任意の文字列を表す。
{ }
{ }内に含まれる文字列にマッチする。
例えば test.{pl,gif,f} は、test.pl test.gif test.f と入力したことになる。

この機能は便利で, * (アスタリスク)は良く使います.

$ cp *.txt work/
$ rm *.txt

< カレントディレクトリ内で末尾が .txt という
ファイルを work 以下に移動させる.
< カレントディレクトリ内で末尾が .txt という
ファイルを消去する.

但しいくら便利だからといって以下のコマンドを実行してはいけません.
筆者はこのせいで卒論の原稿を半分消してしまったことがあります.

$ rm *

絶対に禁止!!!

#### [4.5.5] エイリアス（別名）機能

あるコマンドに対して、別名をつけたいときに用います。

alias 別名＝コマンド名

alias 別名＝'オプション付きのコマンド名'

お薦め： rm -i を rm と変更

$ echo "hello world" > hello.txt
$ rm hello.txt
$ echo "hello world" > hello.txt
$ alias rm='rm -i'
$ rm hello.txt

< hello.txt ファイルを作成
< hello.txt ファイルを削除
< hello.txt ファイルを作成
< rm -i を rm として登録
< hello.txt ファイルを削除

#### [4.5.6] ジョブ制御

ジョブ（Job）とは、ユーザがコンピュータに行なわせる仕事の単位です。

似た意味を持つ言葉に、タスクとプロセスがありますが、
この２つは共にマルチプログラミングの目的で、
コンピュータがＣＰＵ（中央演算処理装置）に行わせる仕事の単位です。
ジョブは、複数のジョブステップから構成されることがありますから、
ジョブとタスクは一致するとは限りません。

bash には、１つのシェルで複数のジョブを切替えながら、
並行して作業を行う機能があります。これをジョブ制御と呼びます。

フォアグランドジョブ：
通常シェルでコマンドを実行すると、その作業はジョブとして登録され、
そのコマンドが終了するまで次のコマンドを実行することが出来ません。
このような状態にあるジョブを"フォアグランドジョブ"と言います。
バックグラントジョブ：
これに対して、コマンドの末尾に & を付けて実行すると、
シェルはコマンドの終了を待たずに、すぐ次のコマンドを受け付ける状態になります。
このように、即座に次のジョブを実行できるよう、
背後で実行されている状態のジョブを"バックグランドジョブ"と言います。
バックグランドジョブとして動作しているジョブの一覧を表示させるには、
jobs コマンドを用います。

上記２種のジョブを制御するために、
bash には fg, bg, jobs コマンド、そして & が用意されています。

はじめフォアグランドジョブとして起動されたコマンドを、
バックグランドジョブに変更するには、
（フォアグランドジョブが実行されているために）プロンプトが表示されていない状態の端末で、
Ctrl-z（コントロール・キーを押しながら z キーを押す）として、
ジョブを中断させます。

$ kterm &
$ xclock
^Z
[2]+ Stopped xclock

< Ctrl-z を押します
> ジョブ番号[2]の xclock が停止しました

次に jobs と打ち込み、現在このシェルから実行中のジョブ一覧を表示させます。

$ jobs
[1]- Running kterm &
[2]+ Stopped xclock

> ジョブ番号[1]の kterm が実行中です
> ジョブ番号[2]の xclock が停止中です

xclock より前に kterm が実行されていたので、上のような表示になります。
[ ]の中の数字はジョブの番号を表します。
＋は "current job"、- は"previous job"と呼ばれ、
ジョブの切替え対象となる順番を表しています。

bg コマンドを用いると、
フォアグランドジョブをバックグランドジョブに切り替えることが出来ます。
（bg の後に % ジョブ番号と入力）

$ bg %2
[1]- Running kterm &
[2]+ Running xclock &

> ジョブ番号[1]の kterm が実行中です
> ジョブ番号[2]の xclock が実行中です

逆に、バックグランドジョブをフォアグランドジョブに切り替えるには、
fg コマンドを用います。（ジョブ番号の指定の仕方は、bg コマンドと同様）

$ fg %1
kterm

#### [4.5.7] ファイル、コマンド名の補完機能

bash には、途中まで打ち込まれた内容を元に、
ファイルやコマンドを補完する機能が備わっています。
具体的には、目的の文字列を何文字か入力し、Tab キーを押します。
複数候補が存在する場合は、Tab キーを２回押すことで、
その一覧を表示させることが出来ます。
この機能は他にも、シェル変数、ユーザー名、ホスト名なども補完してくれます。

Tab 以外の補完機能

キー操作 意味
Esc ? 補完候補のリストを一覧する。
Esc / ファイル名として補完を行なう。
Esc ! コマンドとして補完を行なう。
Esc Tab 以前に実行したコマンドの補完を試みる。

### [4.6] シェルの設定 (Bash の場合)

Bash を例にして設定の方法をみてみましょう. システム自体の Bash の
設定ファイルは /etc/profile です. そこには環境変数 PATH やシェル変数
PS1 が定義されています.

個人で環境変数やシェル変数を変更する場合, ホームディレクトリ以下に
存在する .bashrc, .bash_profile を編集します.
例えば自分の作成したプログラムやスクリプトの置場にも PATH を通す場合,
.bashrc や .bash_profile を編集する必要があるでしょう.
この 2 つのファイルの役割は以下のようになっています.

.bashrc と .bash_profile の役割

ファイル名 役割
.bash_profile ログインシェルの設定.
.bashrc ログインシェル以外のシェルの設定

ログインシェルとはユーザがログインした時直後に起動されるシェルのことです
ターミナル(kterm 等)を起動すると一緒にシェルも起動されますが,
そのシェルは .bashrc を読み込んでいます.
2 つ設定ファイルがあって紛らわしいかもしれませんが, 混同しないように
しましょう.

.bash_profile,.bashrc 共に「シェルスクリプト」になっています
(シェルスクリプトに関しては後述します. ).
それらのファイルの中身はコマンドが羅列してあると考えて下さい.
ですから ls --color を ls にエイリアスし, LANG 環境変数を日本語に
したかったらファイル内に以下の 2 行だけ書いておけば良いです.

$ alias ls='ls --color'
$ export LANG=ja_JP.ujis

最終更新日：
2002/10/24(やまだまなぶ)
Copyright © 2002 inex