前の記事では、変数・if・for を使って、ファイルを自動で整理するスクリプトを作りました。スクリプトが書けるようになると、次に出会うのが「止まらない」問題です。
私も、くり返しのスクリプトで終わりの条件を書き忘れて、画面に同じ文字がずっと流れ続けたことがあります。あわててターミナルを閉じたのですが、あとで調べたら、裏で動かしていた別のスクリプトは、まだ動き続けていました。「今なにが動いているのか」を見る方法を知らなかったんです。
この記事では、動いているプログラム(プロセス)を ps と top で見て、kill で安全に止める方法を、練習用の sleep を使って確かめていきます。
- プロセスとは何か、PID(プロセスの番号)とは何か
-
ps・ps aux・pgrepで、動いているものを探す方法 -
topで、パソコンを重くしているものを見つける方法 -
Ctrl + C・Ctrl + Z・jobs・fg・bgの使い方 -
killとkill -9の違い
- シェルスクリプトを作って、
./ファイル名で動かせる - パイプ(
|)とgrepを使える - ユーザーと
sudoのしくみがわかる
まだの方は、前の記事「シェルスクリプトの変数・if・for|くり返し作業を自動化【初心者向け】」から読むのがおすすめです。
- トークン:ログインした状態や、使ってよい範囲を表す文字列。APIキーと同じく、パスワードと同じように人に見せてはいけません
- 変数:値を入れておく、名前つきの箱
- スクリプト:やりたい処理を順番に書いておき、まとめて実行できるファイル(小さなプログラム)
- sudo:許可されたユーザーが、コマンドの前につけて、そのコマンドだけを管理者(root)の権限で実行するしくみ。パスワードを聞かれたら、root ではなく自分のパスワードを入れます
用語で迷ったら、連載のまとめ記事の「よく出てくる用語ミニ辞典」でも確かめられます。
結論:プロセスは「動いているプログラム」、PID はその番号
| やりたいこと | コマンド |
|---|---|
| 今のターミナルで動いているものを見る | ps |
| パソコン全体で動いているものを見る | ps aux |
| 名前で探して PID を知る | pgrep -a 名前 |
| 重いものをリアルタイムで見る | top(q で終わる) |
| 目の前のコマンドを止める | Ctrl + C |
| 番号を指定して止める | kill PID |
| どうしても止まらないときだけ | kill -9 PID |
準備:練習用のディレクトリを作る
練習は ~/linux-practice/process-test の中で行います。
- 1
- 2
- 3
mkdir -p ~/linux-practice/process-test
cd ~/linux-practice/process-test
pwdここから先の出力例は、Debian 13での実行例です(ユーザー名 kaito・パソコン名 demo のダミー環境)。UbuntuやWSL(=Windows の中で Linux を動かせる、Microsoft のしくみ)では、表示が少し違うことがあります。
(例)
- 1
- 2
- 3
- 4
kaito@demo:~/linux-practice/script-test$ mkdir -p ~/linux-practice/process-test
kaito@demo:~/linux-practice/script-test$ cd ~/linux-practice/process-test
kaito@demo:~/linux-practice/process-test$ pwd
/home/kaito/linux-practice/process-testプロセスと PID
コマンドやアプリを動かすと、Linux はそれをプロセスとして管理し、1つずつに PID(プロセスID)という番号をつけます。今使っているシェル(bash)も、プロセスの1つです。自分のシェルの PID は $$ で見られます。
- 1
echo $$(例)
- 1
- 2
kaito@demo:~/linux-practice/process-test$ echo $$
48ps:動いているものを見る
ps だけだと、今のターミナルで動いているものが表示されます。
- 1
ps(例)
- 1
- 2
- 3
- 4
kaito@demo:~/linux-practice/process-test$ ps
PID TTY TIME CMD
48 pts/0 00:00:00 bash
134 pts/0 00:00:00 psパソコン全体で動いているものを見るには ps aux を使います。とても多いので、head で先頭だけ見ましょう。
- 1
ps aux | head -10(例)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
kaito@demo:~/linux-practice/process-test$ ps aux | head -10
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 20516 11612 ? S 02:53 0:00 python3 /opt/drv/ptydrv4.py /opt/drv/steps_lv3.json /opt/drv/lv3
root 3 0.0 0.0 0 0 ? Zs 02:53 0:00 [su] <defunct>
root 24 0.0 0.0 0 0 ? Zs 02:53 0:00 [su] <defunct>
root 46 0.0 0.0 7508 4660 pts/0 Ss 02:54 0:00 su - kaito
kaito 48 0.0 0.0 10276 5588 pts/0 S 02:54 0:00 -bash
kaito 135 0.0 0.0 10844 4176 pts/0 R+ 02:56 0:00 ps aux
kaito 136 0.0 0.0 7076 2120 pts/0 S+ 02:56 0:00 head -10※ PID 1 の python3 /opt/drv/… の行と、[su] <defunct> の行は、検証用の環境だけに出るものです(検証のための仕組みと、その後に残った終わったプロセス)。ふだんの Linux では、PID 1 には systemd(=Linux の起動や、サービスの起動・停止・自動起動を管理するしくみ)や init などが表示され、もっとたくさんの行が並びます。
よく見る列は次のとおりです。
| 列 | 意味 |
|---|---|
| USER | だれが動かしているか |
| PID | プロセスの番号 |
| %CPU | CPU をどのくらい使っているか |
| %MEM | メモリをどのくらい使っているか |
| COMMAND | 動いているコマンドの名前 |
root(=Linux の管理者ユーザー)が動かしているものがたくさんあるはずです。これらは Linux が動くために必要なもので、ふだんは触りません。
練習用のプロセスを動かす
止める練習のために、sleep(指定した秒数だけ待つだけのコマンド)を使います。うしろに & をつけると、裏(バックグラウンド)で動かして、すぐに次のコマンドを打てるようになります。
- 1
- 2
- 3
sleep 300 &
sleep 301 &
jobs(例)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
kaito@demo:~/linux-practice/process-test$ sleep 300 &
[1] 137
kaito@demo:~/linux-practice/process-test$ sleep 301 &
[2] 138
kaito@demo:~/linux-practice/process-test$ jobs
[1]- Running sleep 300 &
[2]+ Running sleep 301 &[1] 1234 の [1] はジョブ番号(このターミナルの中での番号)、1234 は PID です。
pgrep と ps aux | grep で探す
名前で探すときは pgrep が便利です。-a をつけると、コマンドの全体も表示されます。
- 1
- 2
pgrep -a sleep
ps aux | grep "[s]leep 30"(例)
- 1
- 2
- 3
- 4
- 5
- 6
kaito@demo:~/linux-practice/process-test$ pgrep -a sleep
137 sleep 300
138 sleep 301
kaito@demo:~/linux-practice/process-test$ ps aux | grep "[s]leep 30"
kaito 137 0.0 0.0 7068 2088 pts/0 S 02:56 0:00 sleep 300
kaito 138 0.0 0.0 7068 2152 pts/0 S 02:56 0:00 sleep 301grep "[s]leep" のように1文字目を [ ] で囲むのは、grep 自身が検索結果にまざらないようにするための、ちょっとしたコツです。
top:重くしているものをリアルタイムで見る
パソコンが重いときは top で、CPU やメモリ(=プログラムが動くときに使う作業机のような場所)をたくさん使っているものを探せます。
- 1
top(例)
- 1
- 2
- 3
- 4
- 5
- 6
kaito@demo:~/linux-practice/process-test$ top
top - 02:56:50 up 12:14, 0 users, load average: 0.40, 0.27, 0.33
Tasks: 8 total, 1 running, 5 sleeping, 0 stopped, 2 zombie
%Cpu(s): 0.8 us, 0.3 sy, 0.1 ni, 98.6 id, 0.0 wa, 0.0 hi, 0.2 si, 0.0 st
MiB Mem : 16002.3 total, 3472.9 free, 5255.5 used, 7706.0 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 10746.8 avail Memtop の画面の上の部分です(数字は数秒ごとに変わります)。Tasks の行の 2 zombie は、上の ps aux で見えた検証用の環境の事情によるもので、ふだんの環境では 0 のことがほとんどです。
top の画面では、次のキーが使えます。
-
P(大文字):CPU を使っている順に並べる -
M(大文字):メモリを使っている順に並べる -
q:topを終わる
数秒ながめたら、q で終わりましょう。Debian 13 では、q で終わっても top の最後の表示が画面に残り、その下にプロンプトが出ました。htop という、色つきで見やすい道具もあります。気になる方は、Lv2 の apt の記事を参考に入れてみてください。
top は画面が動き続けるので、結果をコピーして AI に聞きたいときには向いていません。そんなときは、ps aux --sort=-%cpu | head -10 と打つと、CPU をたくさん使っている順に並べた一覧が、止まった状態で表示されます。
-
--sort=-%cpu:%CPUの列で並べかえる。-がついているので、大きい順になる -
| head -10:先頭の10行だけ表示する(1行目は見出しなので、プロセスは9つ)
検証では、CPU を使うプロセスがある状態で見るために、yes(同じ文字を出し続けるコマンド)を30秒だけ裏で動かしてから打ちました。timeout 30 は「30秒たったら止める」、> /dev/null は「出てきた文字を捨てる」という意味です。head だけでも先頭の10行が出るので、head -10 と同じ結果になります。
- 1
- 2
- 3
timeout 30 yes > /dev/null &
ps aux --sort=-%cpu | head
wait; echo $?(例)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
kaito@demo:~$ timeout 30 yes > /dev/null &
[1] 955
kaito@demo:~$ ps aux --sort=-%cpu | head
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
kaito 956 98.4 0.0 7064 2016 pts/0 R 06:20 0:01 yes
kaito 938 0.7 0.0 21868 12264 ? Ss 06:20 0:00 /usr/lib/systemd/systemd --user
kaito 949 0.3 0.0 10456 5916 pts/0 S 06:20 0:00 -bash
root 1 0.1 0.0 23580 14508 ? Ss 06:15 0:00 /lib/systemd/systemd --log-target=console
Debian-+ 384 0.0 0.1 40380 24492 ? Ss 06:15 0:00 /usr/sbin/exim4 -bdf -q30m
message+ 132 0.0 0.0 8364 4912 ? Ss 06:15 0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
root 135 0.0 0.0 19104 9100 ? Ss 06:15 0:00 /usr/lib/systemd/systemd-logind
root 66 0.0 0.0 42784 15800 ? Ss 06:15 0:00 /usr/lib/systemd/systemd-journald
root 131 0.0 0.0 8344 2828 ? Ss 06:15 0:00 /usr/sbin/cron -f
kaito@demo:~$ wait; echo $?
[1]+ Exit 124 timeout 30 yes > /dev/null
0いちばん上に yes が来て、%CPU が 98.4 になっています。CPU を1つ分ほぼまるごと使っている、という意味です。30秒たつと timeout が止め、wait のところで Exit 124(timeout が時間切れで止めた印)が表示されました。そのあとの 0 は、wait の終了コード(=コマンドが終わったときに返す数字)です。PID や数字は、みなさんの画面では変わります。
メモリの多い順なら、%cpu を %mem に変えます。この記事の最後の「AIに聞こう」で貼るのは、この一覧です。
kill:番号を指定して止める
さっきの sleep 300 を止めます。PID はみなさんの画面に出た番号に置きかえてください。
- 1
- 2
- 3
- 4
pgrep -a sleep
kill 1234
jobs
pgrep -a sleep(例)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
kaito@demo:~/linux-practice/process-test$ pgrep -a sleep
137 sleep 300
138 sleep 301
kaito@demo:~/linux-practice/process-test$ kill 137
kaito@demo:~/linux-practice/process-test$ jobs
[1]- Terminated sleep 300
[2]+ Running sleep 301 &
kaito@demo:~/linux-practice/process-test$ pgrep -a sleep
138 sleep 301Terminated(終わった)の表示は、kill を打った直後ではなく、次に jobs を打ったときに出ました。
kill は「終わってください」とお願いする合図(TERM という合図)を送ります。ふつうのプログラムは、これで後片づけをしてから終わります。
ジョブ番号で止めることもできます。% をつけて番号を書きます。
- 1
- 2
- 3
jobs
kill %2
jobs(例)
- 1
- 2
- 3
- 4
- 5
kaito@demo:~/linux-practice/process-test$ jobs
[2]+ Running sleep 301 &
kaito@demo:~/linux-practice/process-test$ kill %2
kaito@demo:~/linux-practice/process-test$ jobs
[2]+ Terminated sleep 301kill -9 は最後の手段
kill でお願いしても止まらないときだけ、kill -9 を使います。これは「後片づけなしで、今すぐ強制終了」の合図(KILL)です。練習用の sleep でためしてみましょう。
- 1
- 2
- 3
sleep 302 &
kill -9 $!
jobs(例)
- 1
- 2
- 3
- 4
- 5
kaito@demo:~/linux-practice/process-test$ sleep 302 &
[1] 145
kaito@demo:~/linux-practice/process-test$ kill -9 $!
kaito@demo:~/linux-practice/process-test$ jobs
[1]+ Killed sleep 302Killed も、次の jobs で表示されました。日本語の環境では、Killed は 強制終了、このあと出てくる Stopped は 停止 と表示されます(Terminated は英語のままでした)。
$! には、「いちばん最後に裏で動かしたものの PID」が入っています。kill -9 で止めると、保存の途中だったデータが壊れることがあります。まずは kill、だめなら kill -9 の順番を守りましょう。
Ctrl + C と Ctrl + Z
目の前で動いているコマンドは、Ctrl + C で止められます。止まらないスクリプトを作って、ためしてみましょう。nano loop.sh で、次の中身を書いて保存します。
- 1
- 2
- 3
- 4
- 5
- 6
#!/bin/bash
# 1秒ごとに時刻を表示しつづける練習用スクリプト
while true; do
echo "動いています $(date +%T)"
sleep 1
done- 1
- 2
chmod u+x loop.sh
./loop.sh数行表示されたら、Ctrl + C を押します。
(例)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
kaito@demo:~/linux-practice/process-test$ chmod u+x loop.sh
kaito@demo:~/linux-practice/process-test$ ./loop.sh
動いています 02:57:12
動いています 02:57:13
動いています 02:57:14
動いています 02:57:15
^CCtrl + Z は、止めるのではなく一時停止です。一時停止したものは fg で目の前に戻し、bg で裏で続きを動かせます。
- 1
./loop.sh数行表示されたら Ctrl + Z を押し、続けて次を打ちます。
- 1
- 2
jobs
fgもう一度表示が流れ始めたら、Ctrl + C で止めます。
(例)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
kaito@demo:~/linux-practice/process-test$ ./loop.sh
動いています 02:57:17
動いています 02:57:18
動いています 02:57:19
動いています 02:57:20
^Z
[1]+ Stopped ./loop.sh
kaito@demo:~/linux-practice/process-test$ jobs
[1]+ Stopped ./loop.sh
kaito@demo:~/linux-practice/process-test$ fg
./loop.sh
動いています 02:57:22
動いています 02:57:23
動いています 02:57:24
^Cfg を打つと、最初に ./loop.sh とコマンドの名前が表示されて、続きが動き始めます。
Ctrl + Z をずっと放っておかない Ctrl + Z は止めたのではなく、一時停止しているだけです。うっかり押したまま忘れると、ずっと残り続けます。ターミナルを閉じようとしたときに「There are stopped jobs.」と出たら、jobs で確かめて、fg で戻してから Ctrl + C で止めましょう。
後片づけ:練習のプロセスが残っていないか確かめる
- 1
- 2
- 3
jobs
pgrep -a sleep
pgrep -af loop.sh(例)
- 1
- 2
- 3
kaito@demo:~/linux-practice/process-test$ jobs
kaito@demo:~/linux-practice/process-test$ pgrep -a sleep
kaito@demo:~/linux-practice/process-test$ pgrep -af loop.sh3つとも何も表示されなければ、練習のプロセスは残っていません。
sudo kill で root が動かしているプロセスを止めたり、kill 1(PID 1 は Linux 全体の親になる大事なプロセス)を送ったり、kill -9 -1(自分が動かしているものを全部止める書き方)を使ったりすると、システムが正しく動かなくなったり、ログアウトされたりします。また、pkill や killall は名前に合うものをまとめて止めるので、関係ないものまで止めてしまうことがあります。この記事では試しません。止めるのは、pgrep -a で中身を確かめた、自分で動かしたものだけにしましょう。
🤖 詰まったらAIに聞こう:重い原因がわからない・止めていいかわからない
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
Linuxの初心者です。パソコンが重いので、原因になっているプロセスを調べています。
次の ps(または top)の結果を見て、どれが重さの原因になっていそうか教えてください。
それぞれのプロセスが何をしているものか、止めても大丈夫かどうかも、やさしく説明してください。
止める場合は、kill -9 ではなく、安全な方法から順番に教えてください。
【使っている環境】WSLのUbuntu など
【困っていること】例:ファンが回りっぱなしで、動きが遅い
【ps aux --sort=-%cpu | head -10 の結果(ユーザー名などは置き換え済み)】ここに貼る
【自分で動かした覚えのあるもの】例:Python のスクリプトps aux の COMMAND の列には、プログラムに渡した値がそのまま表示されます。コマンドの中にAPIキー、トークン、パスワードを書いて動かしていると、それも見えてしまいます。AI に貼る前に、必ず「***」に置き換えてください。
よくある質問
Q. Ctrl + Z のあとの bg は、どう使うのですか?
Ctrl + Z で一時停止したあと bg と打つと、止めたものが裏で続きを動かし始めます。ターミナルはすぐに次のコマンドを打てる状態に戻ります。ただし loop.sh のように画面に表示し続けるものは、裏で動いていても表示が流れてくるので、fg で目の前に戻してから Ctrl + C で止めるか、kill %1(ジョブ番号の前に %)で止めます。
Q. PID は毎回同じ番号ですか?
いいえ。PID は動かすたびに、あいている番号がつけられます。この記事の 137 や 145 も、みなさんの画面では別の番号になります。kill するときは、必ずその場で pgrep -a や jobs で確かめた番号を使いましょう。
Q. & で裏で動かしたまま、ターミナルを閉じるとどうなりますか?
ふつうは、ターミナルを閉じると、そこから動かしたものも一緒に終わります。ターミナルを閉じても動かし続けたいときは、次の記事の nohup や tmux(=ターミナルの作業画面を残したまま切りはなし、あとでまた戻れる道具)を使います。
まとめ
- 動いているプログラムをプロセスと呼び、1つずつに PID という番号がつく
-
psは今のターミナル、ps auxは全体、pgrep -aは名前で探す -
topで重いものをリアルタイムで見られる。qで終わる - コマンドのうしろに
&をつけると裏で動く。jobsで一覧 - 止めるときは
Ctrl + Cかkill PID。kill -9は最後の手段 -
Ctrl + Zは一時停止。fgで戻す - 止めるのは、自分で動かしたものだけ
次の記事では、今回少しだけ使った & の続きです。ターミナルを閉じても、ログアウトしても止まらないように動かす nohup と tmux を使ってみます。
次に読む記事
関連する記事
- Cursorを快適に動かすためのマシン要件まとめ【AI使うなら特に必見】:パソコンが重い原因を、メモリや CPU の面から知りたい方に
- Pythonで毎朝のCSV集計を自動化する(pandas+定期実行):Python のスクリプトを定期的に動かしたい方に
- Cursorにエラーを直してもらう5ステップ|エラーの渡し方・頼み方・直った後の確認まで:止まらないスクリプトの直し方を AI に相談したい方に