Linuxの勉強中、ログアウトしようとしたところ…見えないところで何者かが動いていて、ログアウトできませんでした。そこでバックグラウンドジョブに遭遇したので調べてまとめてみました。
【環境】Cygwinで勉強中
Version 3.1.4-1
#そもそもバックグラウンドジョブとは
バックグラウンド=人の見えないところ
ジョブ=処理
∴人の見えないところで行われている処理
#なぜ必要
###その前にジョブさんたちの紹介
この魔法のコマンドjobsでアクティブなジョブさんたちがリストで表示されます。
$ jobs #一覧
$ jobs -l #プロセスID[PID]も表示
$ jobs -p #プロセスID[PID]のみ表示
$ jobs -r #実行中(running) プロセスのみ表示
$ jobs -s #停止中(stopped) プロセスのみ表示
$ sleep 120 #これ1ジョブさん
$ sleep 10 & echo “I’m a job“ #これも1ジョブさん
$ echo “I’m a echo” && echo “me too“ #これも1ジョブさん
###ジョブには表舞台と裏舞台
####表舞台のフォアグラウンドジョブ
先ほどのジョブさんたち、普通に実行するとフォアグラウンドジョブとして実行されます。つまり前面で見える部分のジョブ。
ジョブが見えている(見守らなきゃいけないジョブさん)=他のジョブはできない
∴フォアグラウンドジョブ実行中はシェルが停止状態なので他のジョブはできない
$ sleep 120 #120秒見守る
####バックグラウンドジョブ
1つのジョブさんをバックグラウンドの裏舞台で実行なら他のジョブさんを実行することができる。
でも裏舞台にいるので、キーボードからのシグナルは受け取ってくれません。
∴バックグラウンド実行中はジョブさんとシェルが同時に動いている状態
$ sleep 120 &
#&をつけてバックグラウンドで実行
&がミソですね。
##なぜ必要かというと
人間はシングルタスクしかできないので、マルチタスクはパソコンさんにお願いするため。
例えば、食器を洗いながら読書はできません。だから食洗機を使って洗ってもらっている時間に読書ができる。みたいな。
#実際にやってみる
$ sleep 120
#ctrl+zでジョブさんの中止
$ sleep 120 &
$ sleep 120 &
$ sleep 120 &
$ sleep 120 &
$ jobs #一覧表示
[1]+ 停止 sleep 120
[2] 実行中 sleep 120 &
[3] 実行中 sleep 120 &
[4] 実行中 sleep 120 &
[5]- 実行中 sleep 120 &
# + は現在実行中のジョブさん
# - は直前に実行されたジョブさん
#止め方
実行できたはいいがバックグラウンドで実行中のままログアウトしようとすると足止めを喰らうことになるだろう。
ここで紹介する止め方は2通り
1. killコマンドでプロセスを終了
2. fgコマンドでフォアグラウンドジョブにしてから終了
###1. killコマンドでプロセスを終了
$ jobs -l #-lオプションでプロセスID[PID]表示
#終了したいジョブさんのPID確認
[1]+ 1663 Stopped sleep 120
[2] 1674 実行中 sleep 120 &
[3] 1675 実行中 sleep 120 &
[4] 1676 実行中 sleep 120 &
[5] 1677 実行中 sleep 120 &
[6] 1678 実行中 sleep 120 &
[8] 1680 実行中 sleep 120 &
[9] 1681 実行中 sleep 120 &
[10] 1682 実行中 sleep 120 &
[11]- 1683 実行中 sleep 120 &
$ kill 1674
#終了したか確認
$ jobs -l
[1]+ 1663 Stopped sleep 120
[2] 1674 Terminated sleep 120
[3] 1675 実行中 sleep 120 &
[4] 1676 実行中 sleep 120 &
[5] 1677 実行中 sleep 120 &
[6] 1678 実行中 sleep 120 &
[8] 1680 実行中 sleep 120 &
[9] 1681 実行中 sleep 120 &
[10] 1682 実行中 sleep 120 &
[11]- 1683 実行中 sleep 120 &
###2. fgコマンドで終了
fgコマンドにジョブ番号を渡してctrl+cでジョブを終了する。
$ sleep 120 &
[2] 1686
$ jobs
[1]+ 停止 sleep 120
[2]- 実行中 sleep 120 &
#fgコマンドにジョブ番号を渡す
$ fg 2
sleep 120
#ここで ctrl+C でジョブの終了
#停止中のジョブさんは...
ctrl+zで停止したジョブさんがずっと残っている。
復活→終了で処理。
※fgコマンドもbgコマンドも実行すると、ジョブは再開される。
・ fgコマンドでフォアグラウンドジョブとして再開し、終了させる。
$ jobs
[1]+ 停止 sleep 120
$ fg 1 #fgコマンドにジョブ番号を渡す
sleep 120
$ sleep 120
[1]+ 停止 sleep 120
#ctrl+cで終了
・ bgコマンドでバックグラウンドジョブとして再開してkill
$ bg 1 #bgコマンドにジョブ番号を渡す
[1]+ sleep 120 &
$ jobs -l #-lオプションでPID確認
[1]+ 1687 実行中 sleep 120 &
$ kill 1687
$ jobs
[1]+ Terminated sleep 120
#プロセスとジョブの違い...?
killはプロセスIDだし、fgとbgはジョブ番号だし。
プロセスとジョブの違いってなによ、、、、