プロセスとシグナル

INPUT · スライド

うしろで動かす(`&` と `jobs`)

01 / 08

返ってこない、という困りごと

こんな経験はもうあるよね。

~ $ sleep 60

打った瞬間から、プロンプトが返ってこない。60秒のあいだ、何も打てないんだ。

これは壊れているのではないよ。コマンドを1つ打つと、シェルはそれが終わるまで待つように作られているんだ。この「前に出ている」状態を フォアグラウンド(foreground)と呼ぶよ。

困るのは、時間のかかる仕事を頼んだときだね。

  • 大きなファイルを固めている
  • ログをずっと眺めている
  • サーバーを動かしている

そのあいだ端末が1つ使えなくなるのは、もったいないでしょう。

この回でやるのは、同じ端末で仕事を並べる方法だよ。

02 / 08

& でうしろに回す

行の最後に & を付けると、シェルは待たなくなるよ。

~ $ sleep 60 &[1] 83~ $

すぐにプロンプトが返ってきたね。sleep は動いたままだよ。この状態を バックグラウンド(background)と呼ぶんだ。

出てきた [1] 83 は2つの数だよ。

出た数名前誰が付けた番号か
[1]ジョブ番号あなたのシェルが付けた
83PIDLinux ぜんたいで付けた

ここが今日の山場だよ。この2つは別の番号なんだ。

ジョブ番号は「このシェルが預かっている仕事の1番目」という意味で、1から順に増える。別の端末を開いたら、そこにも [1] があるよ。

PID は前のレッスンでやった、機械の中で世界に1つの番号だね。

03 / 08

jobs で預けた仕事を見る

うしろに回したものは jobs で一覧できるよ。

~ $ sleep 60 &[1] 83~ $ sleep 90 &[2] 84~ $ jobs[2]+  Running                    sleep 90[1]-  Running                    sleep 60

新しいものが上に来るよ。ps とは並びが逆だね。

真ん中の言葉が状態だよ。

表示意味
Running動いている
Stopped止めてある(消えてはいない)
Done終わった

番号のうしろの印にも意味があるんだ。

  • + … いま指されているジョブ(番号を省くとこれが選ばれる)
  • - … その次の候補

PID も見たいときは -l を足すよ。

~ $ jobs -l[2]+  84 Running                 sleep 90[1]-  83 Running                 sleep 60

ps で探さなくても、自分が預けたものだけが並ぶのが jobs の良さだね。

04 / 08

%1 はシェルの中だけの番号

ジョブ番号を指すときは、頭に % を付けるよ。

~ $ kill %1     ジョブ1番を止める~ $ kill 83     PID 83 を止める

どちらも同じものを止めているけれど、指し方が違うんだ。

%1  → あなたのシェルに聞いて、PID に直してもらう83  → Linux に直接言う

だから %1そのシェルの外では通じないよ。別の端末で kill %1 と打っても、あなたのジョブは止まらない。

打ちやすいのは %1 だね。PID を調べなくていいし、短いからね。

使いたい相手指し方
自分がうしろに回したもの%1 %2
他の端末で動いているものPID(ps で調べる)
名前で全部killall 名前

& で自分が投げたものは %番号、それ以外は PID、という使い分けだよ。

05 / 08

Ctrl-Z で一時停止して bg

困るのは、& を付け忘れて打ってしまったときだよね。打ち直すのはもったいない。

そんなときは Ctrl-Z を押すんだ。

~ $ sleep 60^Z[1]+  Stopped                    sleep 60~ $

プロンプトが戻ってきたね。sleep止まって残っているよ(Stopped)。消えたわけではないんだ。

そこから2つに分かれるよ。

bg %1    うしろで動かし続ける(& を付けたのと同じ形になる)fg %1    前に戻して、終わるまで待つ

bg は background、fg は foreground の略だね。

~ $ bg %1[1] sleep 60~ $ jobs[1]+  Running                    sleep 60

StoppedRunning に変わったでしょう。

Ctrl-Zbg の2手で、打ち直さずにうしろへ回せるんだ。これは覚えておくと本当に助かるよ。

06 / 08

Ctrl-CCtrl-Z は違う

似ている2つを並べておこう。前のレッスンでやった合図(シグナル)の言葉で言うとこうだよ。

キー送る合図どうなるか
Ctrl-CINT終わる(消える)
Ctrl-ZTSTP止まる(残る)

Ctrl-C は取り消し、Ctrl-Z は一時停止だね。

止まっているあいだ、そのプロセスは何も進めないよ。数を数えるプログラムなら、数が増えなくなる。時計も進まない。

Stopped   → 息はしているが、動いていない

もう要らないと分かったら、止めたまま置いておかずに消そう。

~ $ jobs[1]+  Stopped                    sleep 60~ $ kill %1

止まっているものにも kill は届くよ。

そして戻すときは bgfg を使ってね。kill -CONT でも動きはするけれど、シェルの一覧が Stopped のまま食い違ってしまうんだ。

07 / 08

うしろの声は割りこむ

うしろに回したものも、画面には遠慮なく書くよ。

~ $ sh oshaberi.sh &[1] 90~ $ lsこんにちは        ← うしろから割りこんだmemo.txt

打っている途中に文字が出てくるので、読みにくいし、打ちまちがえのもとだね。

だから作法はこうだよ。

~ $ sh oshaberi.sh > koe.txt 2>&1 &

先にファイルへ受けてから、うしろに回すんだ。あとで cat koe.txt で落ちついて読めるでしょう。前のレッスンでもこの形を使ったね。

終わるのを待ちたいときは wait だよ。

~ $ sh omoi.sh > log.txt &~ $ wait~ $ echo owatta

waitうしろのぜんぶが終わるまで待つよ。「投げておいて、最後に揃うのを待つ」という書き方は、章11のスクリプトでよく使うからね。

08 / 08

さあ、打ってみよう

この回で使うのはこれだけだよ。

コマンド &        うしろで動かすjobs              預けた仕事の一覧jobs -l           PID も見るfg %1             前に戻して待つbg %1             うしろで動かし続けるkill %1           ジョブ番号で止めるwait              うしろのぜんぶを待つ

そしてキーが2つあるよ。

Ctrl-Z   いま動いているものを止める(残る)Ctrl-C   いま動いているものを終わらせる(消える)

数えるための道具も一緒に使うからね。

~ $ jobs | wc -l > kazu.txt

jobs の出力もただの行なので、wcgrep に渡せるんだ。章4と章5でやったことが、そのまま効くね。

では、返ってこない端末から抜け出す練習をしよう。