計算機基礎A - 7. Linux の簡単な使い方 (2)

Table of Contents

1 プロセス管理

1.1 プロセス

UNIX はマルチタスク OS なので,同時に複数のプログラムを動作させることができます. 動作中のプログラムは「プロセス」という単位で管理されています. ターミナルから ps コマンドを実行してみましょう. すると

$ ps
  PID TTY          TIME CMD
28428 pts/0    00:00:00 bash
31945 pts/0    00:00:00 ps

のような結果が得られます. PID はプロセスID, CMD はコマンドの略です. このように,各プロセスには「プロセスID 」 (PID) という番号で管理されています. ps コマンドに u オプションを指定すると,プロセスの所有者(通常はコマンドを実行したユーザ)に関する情報が得られます.

$ ps u
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
mtkg     28428  0.0  0.2  13280  7612 pts/0    Ss   21:19   0:00 -bash
mtkg     32614  0.0  0.0   6756  1024 pts/0    R+   21:38   0:00 ps u

xw オプションを指定すると他の端末 (TTY) で動作しているプロセスの情報も得られます.

$ ps uxw
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
mtkg       715  0.0  0.0   6724   696 pts/0    R+   21:40   0:00 ps uxw
mtkg     28427  0.0  0.0  17780  1992 ?        R    21:19   0:00 sshd: mtkg@pts/0    
mtkg     28428  0.0  0.2  13280  7612 pts/0    Ss   21:19   0:00 -bash

さらに, a オプションを指定すれば他のユーザのプロセスに関する情報も得られます.

1.2 kill コマンド

プロセスを強制的に終了するには kill コマンドを使います. ただし,これはプログラムが「暴走」したときのための方法ですので,ふだんは通常の方法で終了してください.

例として xload というコマンドを実行し,これを強制終了してみましょう. 次のようにコマンドを実行してください.

$ xload &
$ ps
  PID TTY          TIME CMD
 3206 pts/0    00:00:00 xload
 3344 pts/0    00:00:00 ps
28428 pts/0    00:00:00 bash

xload の PID は 3206 であることがわかります. kill コマンドに PID を指定して実行すると,そのプロセスを強制終了することができます. 次のように入力して xload を強制終了してみましょう.

$ kill 3206

kill コマンドだけではうまく強制終了できないときは -HUP オプションか -KILL オプションを試してください.

$ kill -HUP 3206        # kill では強制終了できない場合の手段
$ kill -KILL 3206       # kill -HUP でも強制終了できない場合の手段

ただし -KILL オプションは「最後の手段」なので,なるべく使わない方がよいでしょう.

1.3 ジョブ

シェルで対話的に処理できるのはひとつのコマンドだけですが,マルチタスク OS の特徴を生かし,別のコマンドを同時に(ただし非対話的に)実行することができます. 非対話的に実行するコマンドをバックグランドジョブ (background job), 対話的に実行するコマンドをフォアグランドジョブ (foreground job) といいます.

コマンドをバックグランドで実行するには、コマンドラインの末尾に & を付けます. 次の例では xeyesxload をバックグランドジョブとして実行しています.

$ xeyes &
[1] 13729
$ xload &
[2] 13730

job コマンドを使うとバックグランドで実行されているジョブの一覧が得られます.

$ jobs
[1]-  Running                 xeyes &
[2]+  Running                 xload &

1列目の数字は「ジョブ番号」と呼ばれます. xeyes のジョブ番号が 1, xload のジョブ番号が 2 となります. ジョブ番号の後の + は「カレントジョブ」を示す記号です. カレントジョブでないものには - という記号が付きます. 上の例では xload がカレントジョブです. 特に指定しなければ,次に紹介するジョブ管理のコマンド fg, bg はカレントジョブに対して働きます.

プロセスID (PID) の代わりに,ジョブ番号を使ってジョブを強制終了することができます. kill コマンドの引数には % にジョブ番号をつけたものを与えます. プロセス番号 1 と 2 のジョブを強制終了するには次のように入力します.

$ kill %1 %2

1.4 fg, bg コマンド

フォアグランドジョブとして実行したコマンドを,途中からバックグランドに変更することもできます. まず xload をフォアグランドジョブとして実行しましょう.

$ xload

ここでキーボードから C-z (コントロールキーを押しながら z を押す)を入力します. これによりフォアグランドジョブが一時停止されます.

$ xload
^Z
[1]+  Stopped                 xload

bg コマンドにプロセス番号 1 を指定して実行すると, 停止中の xload ジョブの実行がバックグランドで再開されます.

$ bg %1
[1]+ xload &

逆に,バックグランドジョブをフォアグランドジョブに変更することもできます. これには fg コマンドを利用します.

$ fg %1
xload

xload コマンドがフォアグランドで実行されているため,シェルのプロンプトが表示されないことに注意してください. フォアグランドジョブは C-c (コントロールキーを押しながら c を押す)で強制終了することができます.

2 リダイレクト・パイプ

2.1 標準入力・標準出力・標準エラー出力

UNIX の各プロセスは標準入力・標準出力・標準エラー出力というデータの入出力を持っています. 特に指定しない限り,標準入力はキーボード入力,標準出力と標準エラー出力はターミナルの画面に設定されています.

2.2 入出力の切り替え(リダイレクト)

通常,シェルが起動したコマンドの入出力は,入力はキーボード(標準入力)から,出力は画面(標準出力)に対して行われます. シェルは起動したコマンドの入出力先を切り替える機能(リダイレクト機能)をもっており,リダイレクトを示す特殊な記号 >, <, >> を見つけるとそれに従った処理を行います. 例えば,

$ echo This is a test >memo.txt

というコマンドを実行すると, echo コマンドの出力は画面に表示されず,代わりにカレントディレクトリに memo.txt というファイルが作られ,そこに echo コマンドの出力が書き込まれます. このとき, memo.txt というファイルがなければ新たに作られ,すでに存在するときは上書きされて古い内容は失われます.

ファイルを上書きせず,コマンドの出力をファイルに追加するには >> を用います.

$ echo This is a test >>memo.txt

memo.txt というファイルがなければ新たに作られる点は > と同じです.

リダイレクトを示す記号と意味をまとめておきます. [..] 内は省略可能です.

[n]<file      デスクリプタ n (省略時 0) で file を読み込み用にオープン
[n]>file      デスクリプタ n (省略時 1) で file を書き込み用にオープン
[n]>>file     デスクリプタ n (省略時 1) で file を追加書き込み用にオープン
<<'EOF'       標準入力を次行から EOF の直前行までとする(ヒアドキュメント)
n>&m          デスクリプタ n の出力をデスクリプタ m に変更
n<&m          デスクリプタ n の入力をデスクリプタ m に変更
[n]<&-        入力デスクリプタ n (省略時 0) をクローズ
[n]>&-        出力デスクリプタ n (省略時 0) をクローズ

2.3 パイプ

パイプ | はコマンドの標準出力と別のコマンドの標準入力をつなぐ働きをします. まず,次のコマンドを実行してみてください.

$ ls -1 /usr/bin

ls は指定したディレクトリに存在するファイルを表示するコマンドで, -1 は1行に1つ表示させるためのオプションです. /usr/bin にはたくさんの実行ファイルがあるので,一度に全部を画面に表示することができません. このような場合は次のようにパイプを利用することができます.

$ ls -1 /usr/bin | less

less はファイルや標準入力の内容を閲覧するための「ページャ」 (pager) と呼ばれるコマンドの一種です. f または SPC (スペースキー)を押すと次のページに進み, b を押すと前のページに戻ります. q を入力すれば終了します.

同じ作業をパイプを使わずに行うには次のようにすればよいでしょう. ただ,一次ファイルが必要になったりして,面倒ですね.

$ ls -1 /usr/bin >ls.out
$ less ls.out
$ rm ls.out

ところで /usr/bin には g で始まる名前の実行ファイルがいくつあるでしょうか? このような作業にもパイプが利用できます. 次のコマンドを実行してみましょう.

$ ls -1 /usr/bin/g* | wc -l
    1133

g* は g で始まるファイルを探すためのワイルドカードです. wc コマンドは文字数や行数などを数えるためのコマンドで, -l オプションを与えると行数のみを表示します. というわけで,このシステムの /usr/bin には 1133 個の実行ファイルがあることがわかりました.

3 ワイルドカード

シェルはコマンドラインを解析して実行すべきコマンドや引数を決定する前に,特殊文字 *, ?, [, ] がコマンドラインに含まれていないか探し,あれば特殊文字部分をファイル名で置き換えます. いま,ユーザのカレントディレクトリに次のようなファイルがあるとしましょう.

$ ls
bear
carrot
ell
rabbit

ここで echo コマンドを使ってファイル名の置換を試してみます. まず,次のようにタイプしてください.

$ echo *
bear carrot ell rabbit

シェルはコマンドラインの解析寺に特殊文字 * をみつけると,カレントディレクトリにあるすべてのファイル名で * 部分を置き換えます. その後でシェルは起動するコマンド名と,コマンドに渡す引数を決定します.

このような文字のことを「ワイルドカード」や「メタ文字」と呼びます. *, ?, [, ] にはそれぞれ次のような意味があります.

*          0 個以上の任意文字と一致
?          任意の 1 文字と一致
[ ]        [ と ] で囲まれた文字のいずれかと一致

今度はカレントディレクトリに次のようなファイルがあったとしましょう.

$ ls
data.txt
data1.txt
data2.txt
data3.txt

data.txt 以外 を削除するには次のコマンドを実行すればよいことになります. rm はファイルを削除するためのコマンドです.

$ rm data?.txt

ワイルドカードは便利ですが,思わぬ動作をすることがありますので,注意して使いましょう.

4 ユーザの環境設定

シェルには「環境変数」と呼ばれるものがあり,ユーザごとの設定などが記録されています. 例えば,コマンドを探すためのディレクトリパス PATH やプロンプトとして表示する文字列を設定する PROMPT などです. 環境変数の名前の先頭に $ をつけると内容を表示することができます. 環境変数 HOME の内容をみるには次のようにします.

$ echo $HOME
/Users/takagi

また env コマンドを引数なしで実行すると,環境変数の一覧を得ることができます.

4.1 PATH

シェルは実行するプログラムを環境変数 PATH に設定されたディレクトリのリストから探します. プログラムが存在していても PATH の中にプログラムのあるディレクトリが含まれていないと見つけてくれません.

ディレクトリのリストは複数のディレクトリをセミコロン : でつないだものになっています. 例えば, PATH の内容が次のようになっていたとしましょう.

$ echo $PATH
/usr/X11/bin:/usr/local/bin:/usr/bin:/bin

この場合,シェルは /usr/X11/bin, /usr/local/bin, /usr/bin, /bin の順に各ディレクトリを検索し,見つかった時点でコマンドを実行します. ただし,コマンド名にパスを含めて指定すると,シェルは PATH に設定されたディレクトリリストを無視して,直接指定されたコマンドを実行します.

$ /bin/date

とすれば /bin/ にある date コマンドが直接実行されます. カレントディレクトリにある a.out というプログラムを実行する場合は, ./a.out と指定すればよいでしょう.

$ a.out
command not found: a.out
$ ./a.out
(今度は正しく実行される)

どの実行ファイルが実行されるか調べるには which コマンドを利用します.

$ which date
/bin/date

したがって,コマンドラインから date コマンドを実行すると, /bin/date というファイルが実行されることがわかります.

PATH に新たなディレクトリを付け加えるには次のようにします.

$ export PATH=/new/directory:$PATH

先頭に付け加えるか,末尾に付け加えるかで検索の優先度が変わることに注意してください.

5 参考文献

Copyright © 2014 Masahiro Takagi. All right reserved.

Date: 2014-06-02 Mon 13:55

Emacs 24.3.1 (Org mode 8.2.6)

Validate