計算機基礎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) といいます.
コマンドをバックグランドで実行するには、コマンドラインの末尾に & を付けます.
次の例では xeyes と xload をバックグランドジョブとして実行しています.
$ 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
先頭に付け加えるか,末尾に付け加えるかで検索の優先度が変わることに注意してください.