第4章 4-1 / システムを観察する

プロセスを見る ― ps・top・kill

このページで叩くコマンドと到達点

前提:第3章までが完了し、~/practice(空ディレクトリ)が存在する状態。ユーザーyumiとグループdevteamは存在するがログインはしていない状態から始めます。ここから第4章「システムを観察する」に入ります。第1〜3章がファイルやテキストという「静的なもの」を扱う技術だったのに対し、第4章はサーバーの「今この瞬間」を観察する技術です。その第一歩として、サーバー上で動いているプロセス※1――バイトの現場で言えば「今誰が何の仕事をしているか」の一覧――を眺め、止め方まで含めて操作できるようになります。

このページではSET 1〜3、合計30行のコマンドを上から順に叩きます。手打ち推奨(コピーは確認用)です。sleep 300 &で自分専用の「動いているプロセス」を作り出し、それをjobsfgbgkillで自在に操るところまで体験します。

SET 1 ― psで動いているプロセスを見る

ubuntu@lightsail: ~
  1. $cd ~
  2. $ps
  3. PID TTY TIME CMD
  4. 1842 pts/0 00:00:00 bash
  5. 1901 pts/0 00:00:00 ps
  6. $ps -f
  7. $ps aux
  8. $ps aux | head
  9. $ps aux | wc -l
  10. $ps aux | grep bash
  11. ubuntu 1842 0.0 0.1 8432 5120 pts/0 Ss 10:02 0:00 bash
  12. $ps aux | grep sshd
  13. $ps -u ubuntu
  14. $ps aux | grep systemd | head -n 3
解説 ― SET 1 で何をしたか

まず1行目のcd ~でホームディレクトリにいることを確認してから始めます。2行目のps(process statusの略)は、今の自分のターミナルで動いているプロセスだけを表示するコマンドです。出力例のように、自分がログインしているシェルのbashと、コマンド自身のpsという、ごくわずかな数しか表示されません。それぞれの行の先頭にある数字はPID※2(プロセスID)で、プロセスひとりひとりに割り振られた「社員番号」のようなものです。3行目のps -fは、同じ自分のターミナルのプロセスを、親プロセスとの関係(PPID)まで含めたやや詳しい形式(full format)で表示するオプションです。

4行目のps auxは、サーバー上で動いているすべてのプロセスを表示するコマンドです。aは他ユーザーのプロセスも含める、uは所有者やCPU・メモリ使用率などの詳細を表示する、xは端末に紐づかないバックグラウンドの処理(サービス類)も含める、という意味を持つオプションの組み合わせです。件数がかなり多いので、5行目ではheadと組み合わせて先頭だけ、6行目ではwc -lと組み合わせて全体で何行(何プロセス)あるかを数えています。サーバーが小さくても、裏側では数十から百以上のプロセスが常に動いていることが実感できるはずです。

7行目のps aux | grep bashは、第3章で身につけたgrepとの連携です。大量のプロセス一覧から「bashという文字列を含む行」だけを絞り込んでいます。出力例のように、自分のログインシェルが1行だけ見つかります。8行目のps aux | grep sshdでは、SSH接続を待ち受けているsshdプロセスが見つかるはずです。今まさに自分がSSHでつながっている、その裏側の仕組みが動いている証拠です。9行目のps -u ubuntuは、grepを使わずに「ubuntuユーザーが所有するプロセスだけ」を指定して絞り込む書き方です。目的に応じて使い分けましょう。最後の10行目ps aux | grep systemd | head -n 3のように、複数のパイプをつなげば「systemdという文字列を含む行の先頭3件だけ」というように絞り込みをさらに重ねられます。

POINT

ps auxの見方で最初に覚えるべきはPID(プロセスID)%CPU%MEMCOMMANDの4列です。「誰が(USER)」「何番の仕事として(PID)」「どれだけ負荷をかけて(%CPU/%MEM)」「何を実行しているか(COMMAND)」がこの1行で読み取れます。

ゆみちゃん
ゆみ

プロセスって「サーバーの中で今動いている仕事」のことだよ! バイト先で例えると、レジ担当・品出し担当・発注担当がそれぞれ別のPID(社員番号)を持って同時に働いてるイメージ。ps auxを叩けば、今サーバーの中で誰が何の仕事をしてるか一覧で見れちゃうんだよ!

SET 2 ― 自分のプロセスをバックグラウンドで動かす

ubuntu@lightsail: ~
  1. $sleep 300 &
  2. [1] 2210
  3. $jobs
  4. [1]+ Running sleep 300 &
  5. $ps aux | grep sleep
  6. $sleep 200
  7. $jobs
  8. $fg
  9. $jobs
  10. $sleep 400 &
  11. $disown
  12. $jobs
解説 ― SET 2 で何をしたか

1行目のsleep 300 &は、「300秒間何もせずただ待つ」だけのコマンドsleepを、末尾に&(アンパサンド)を付けて実行しています。&は「このコマンドをバックグラウンド※3で動かす(裏で走らせたまま、ターミナルの操作はすぐ次に進める)」という指定です。出力例の[1] 2210は「ジョブ番号1、PID 2210で起動した」という報告です。2行目のjobsは、今の自分のターミナルが抱えているバックグラウンドジョブの一覧を表示するコマンドで、出力例のようにRunning(実行中)というステータスが見えます。3行目のようにps aux | grep sleepで探せば、同じプロセスをPIDつきで確認できます。

4行目のsleep 200は、今度は&を付けずに実行しています。&のないコマンドはフォアグラウンド※4(画面を占有する形)で動くため、200秒経つまでターミナルに新しい命令を打てなくなります。ここでCtrl+Zを押すと、実行中のコマンドを一時停止してプロンプトを取り戻すことができます([2]+ Stopped sleep 200のような表示が出ます)。この操作はターミナルへの直接入力のため行番号には現れませんが、5行目のjobsを打つと、1つ目がRunning、2つ目がStopped(停止中)という2つのジョブが確認できるはずです。

6行目のfg(foregroundの略)は、一時停止していた直近のジョブをフォアグラウンドに呼び戻し、続きを実行させるコマンドです。呼び戻したsleep 200はすぐには終わらないので、ここでもCtrl+Zを押して再度一時停止に戻し、7行目のjobsで状態を確認します。8行目のsleep 400 &で3つ目のバックグラウンドジョブを追加し、9行目のdisownは、直近のバックグラウンドジョブをシェルの管理下から外す(ログアウトしても道連れにしない)コマンドです。10行目のjobsで確認すると、disownした分がジョブ一覧から消えていることがわかります(プロセス自体はps auxで見れば動き続けています)。

POINT

Ctrl+Zは「今動いているコマンドを一時停止してプロンプトに戻る」ショートカットです。停止しただけでプロセスは終了していない点に注意してください。続きを再開したいときはfg(フォアグラウンドで)かbg(バックグラウンドで)を使います。

SET 3 ― bg・killとtopで観察する

ubuntu@lightsail: ~
  1. $jobs
  2. [1]+ Stopped sleep 200
  3. $bg
  4. $jobs
  5. $kill %1
  6. $jobs
  7. $ps aux | grep sleep
  8. $kill 2210
  9. $ps aux | grep sleep
  10. $top -n 1
  11. $top
解説 ― SET 3 で何をしたか

1行目のjobsで、SET 2の最後に停止させたままだったsleep 200Stopped状態で残っていることを確認します。2行目のbg(backgroundの略)は、その停止中のジョブを止めたままにせず、バックグラウンドで再開させるコマンドです。fgと違い、プロンプトを占有せずに裏側で動かし続けられます。3行目のjobsで、ステータスがRunningに変わったことを確認しましょう。

4行目のkill %1は、ジョブ番号1のプロセスに終了信号を送るコマンドです。%を付けた数字はjobsコマンドで表示されるジョブ番号を指し、PIDを調べなくてもジョブ番号だけで操作できる点が便利です。5行目のjobsで確認すると、そのジョブが一覧から消えているはずです。6行目のps aux | grep sleepでは、SET 2でdisownしたsleep 400がまだ動いていることが確認できます(ジョブ一覧からは外れていますが、プロセスとしては生きています)。

7行目のkill 2210のように、killにはジョブ番号ではなくPIDを直接指定することもできます。disownされたプロセスはジョブ番号を持たないため、止めたいときはこのようにps auxで調べたPIDを指定します。8行目のps aux | grep sleepで、指定したプロセスが消えている(結果にgrep自身の行しか残らない)ことを確認できれば、無事に終了させられた証拠です。PIDの数字は実行のたびに変わるので、実際に手を動かすときは、自分の画面に表示された番号を使ってください。

9行目のtop -n 1は、-n 1(繰り返し回数1回)を指定して、画面を専有せずに1回分の情報だけを表示してすぐプロンプトへ戻す使い方です。次に説明するオプションなしのtopを試す前に、まずはこちらで出力の形式に慣れておくと安心です。

最後の10行目のtopは、サーバー全体のプロセスをリアルタイムで観察し続けるコマンドです。ps auxがその瞬間のスナップショットだったのに対し、topは数秒おきに自動更新されながら、CPUやメモリを多く使っているプロセスが上位に表示され続けます。ps auxと違って操作しっぱなしの画面(対話型)になるため、他のコマンドを打つには一度この画面を抜ける必要があります。抜け方はキーボードでqを押すだけです。

ubuntu@lightsail: ~ (top)
  1. top - 10:24:31 up 2:03, 1 user, load average: 0.02, 0.05, 0.01
  2. Tasks: 98 total, 1 running, 97 sleeping, 0 stopped, 0 zombie
  3. %Cpu(s): 1.0 us, 0.3 sy, 0.0 ni, 98.5 id, 0.0 wa
  4. MiB Mem : 957.6 total, 112.4 free, 268.9 used, 576.3 buff/cache
  5. PID USER PR NI VIRT RES %CPU %MEM TIME+ COMMAND
POINT

topのような、画面全体を専有して動き続けるコマンドを対話型コマンドと呼びます。抜け方がわからずフリーズしたように感じても、多くの場合はqキー1つで元のプロンプトに戻れます。焦らずqを試すクセをつけましょう。

ゆみちゃん
ゆみ

あたし最初topを叩いたとき、画面が切り替わったまま固まったと思って焦っちゃった! でもqを押すだけでちゃんと戻ってきたよ。あとkillは物騒な名前だけど、あくまで「終了してください」ってお願いする信号だから、自分が動かしたsleepみたいな練習用プロセスに使う分には全然怖くないから安心して!

まとめ

4-1では、サーバー上で動いているプロセスを観察し、自分で作ったプロセスを操作する方法を一通り体験しました。このページで叩けるようになったコマンドを一覧にまとめます。

コマンド何をするか覚え方
ps自分のターミナルのプロセスを表示するprocess status(仕事の状況)
ps auxサーバー上の全プロセスを詳細付きで表示する全ユーザー(a)・詳細(u)・裏方も(x)
ps aux | grep <語>特定のプロセスだけ絞り込む大量の社員名簿から1人を探す
sleep 300 &300秒待つだけの処理をバックグラウンドで起動する&=裏で走らせる合図
jobs自分のターミナルのバックグラウンドジョブ一覧を見る抱えている仕事の一覧
Ctrl+Z実行中のコマンドを一時停止するいったんストップ
fg停止中のジョブをフォアグラウンドで再開するforeground(表舞台に戻す)
bg停止中のジョブをバックグラウンドで再開するbackground(裏方に戻す)
kill %1ジョブ番号1のプロセスを終了させる%数字=ジョブ番号を指定
kill <PID>指定したPIDのプロセスを終了させる社員番号を指名して終了依頼
topプロセスの状況をリアルタイムで観察し続けるqで抜ける対話画面

次のページ「4-2. ディスクとメモリ」では、プロセスという「動き」の観察から一歩進み、ディスク容量やメモリ使用量というサーバーの「体力」を確認する方法を学びます。

脚注 ─ 用語解説
  1. プロセス … 実行中のプログラムの単位。1つのコマンドを実行するたびに、それぞれ固有のプロセスとしてサーバー上で動く。
  2. PID … Process IDの略。動いているプロセスひとつひとつに割り振られる番号で、killなど個別に操作したいときの指定に使う。
  3. バックグラウンド … コマンドを裏側で動かしたまま、ターミナルの操作をすぐ次に進められる状態。末尾に&を付けて起動する。
  4. フォアグラウンド … コマンドが画面(ターミナルの操作)を占有している状態。終了か一時停止までは次の命令を打てない。