スクリプトをバックグラウンドで実行する機会があったんだけど、バックグラウンドで実行するジョブの操作など、全く理解していなかったので備忘録。
■バックグラウンドでコマンドを実行する
| 構文 | 説明 |
| command & | コマンドの最後に「&」を付けます |
■実行中のジョブの確認
| 構文 | 説明 |
| jobs [-lrs][%job番号] | オプション -l:プロセスID表示 -r:実行中のジョブのみ表示 -s:停止中のジョブのみ表示 |
# jobs -l [1]- 1854 Running tail -f /var/log/httpd/access_log & [2]+ 1855 Running tail -f /var/log/messages &
- []内の数値はジョブ番号
- +は現在実行中のジョブ(カレントジョブ)
- -は直前に実行されたジョブ
■フォアグラウンドで実行中のジョブをバックグラウンドへ移行する
| 構文 | 説明 |
| bg %job番号 | ジョブ番号を指定しない場合はカレントジョブが実行される |
[手順]
- Ctrl + zキーでジョブを一時停止
- bgコマンドで%ジョブ番号を指定して実行
# tail -f /var/log/httpd/access_log ← Ctrl+z入力 ^Z [1]+ Stopped tail -f /var/log/httpd/access_log # bg %1 ← "&"バックグラウンドへ移行 [1]+ tail -f /var/log/httpd/access_log & # jobs [1]+ Running tail -f /var/log/httpd/access_log &
■バックグラウンドで実行中のジョブをフォアグラウンドへ移行する
| 構文 | 説明 |
| fg %job番号 | ジョブ番号を指定しない場合はカレントジョブが実行される |
# jobs [1]- Running tail -f /var/log/httpd/access_log & [2]+ Running tail -f /var/log/messages & # fg %2 ← フォアグラウンドへ移行 tail -f /var/log/messages ← tail -fのコマンド実行中でプロンプトに戻らないのでCtrl+zで一時停止してみる ^Z [2]+ Stopped tail -f /var/log/messages # jobs [1]- Running tail -f /var/log/httpd/access_log & [2]+ Stopped tail -f /var/log/messages ← "&"がなくなりフォアグラウンドへ移行
■バックグラウンドジョブの停止・終了
プロセスにIDまたはジョブ番号を指定してシグナルを送ります。
# jobs -l [1]- 1924 Running tail -f /var/log/httpd/access_log & [2]+ 1925 Running tail -f /var/log/messages & ジョブ番号[1]を一時停止 # kill -19 %1 ジョブ確認 # jobs -l [1]+ 1924 Stopped (signal) tail -f /var/log/httpd/access_log [2]- 1925 Running tail -f /var/log/messages & プロセスID:1925(ジョブ番号[2])を終了 # kill -15 1925 ジョブ確認 # jobs -l [1]+ 1924 Stopped (signal) tail -f /var/log/httpd/access_log [2]- 1925 Terminated tail -f /var/log/messages (終了処理中) # jobs -l [1]+ 1924 Stopped (signal) tail -f /var/log/httpd/access_log ※ジョブ番号[2]が終了したため、表示が消える
■ログアウト後もバックグラウンドでプログラム実行
バックグラウンドで実行すればログアウト後もプログラムは継続されますが、今回ネットで調べているとログアウト後もプログラムを実行させるにはnohupコマンドが必要という記事を結構見かけました。参考にしたLPIC レベル1 Release3 にもそのように記載されていました。実際は使用しているシェルによるみたいで、私が普段使用しているbashのデフォルトの設定はシェルからログアウトした際、ジョブにシグナルSIGHUPを送信を送信しないようになっているため、バックグラウンドで実行しているジョブはそのまま継続されるようです。
ログアウト時のSIGHUP送信設定の確認
# 確認 # shopt | grep huponexit huponexit off # ON # shopt -s huponexit # OFF # shopt -u huponexit
試しにバックグラウンドでコマンド実行してログアウトしてみる
# sleepコマンドをバックグラウンドで実行
# sleep 3600 &
[1] 2415
# ジョブコマンドで確認
# jobs -l
[1]+ 2415 Running sleep 3600 &
# psコマンドで確認
# ps aux | grep sleep | grep -v grep
root 2415 0.0 0.0 4072 516 pts/2 S 02:01 0:00 sleep 3600
# pstreeコマンドでも確認
# pstree -p
init(1)-+-auditd(1033)---{auditd}(1034)
|-crond(1193)
|-master(1183)-+-pickup(1875)
| `-qmgr(1190)
|-mingetty(1206)
|-mingetty(1208)
|-mingetty(1210)
|-mingetty(1212)
|-mingetty(1217)
|-mingetty(1221)
|-ntpd(1107)
|-rsyslogd(1049)-+-{rsyslogd}(1050)
| |-{rsyslogd}(1052)
| `-{rsyslogd}(1053)
|-sshd(1099)---sshd(2153)---sshd(2156)---bash(2157)---su(2265)---bash(2269)-+-pstree(2419)
| `-sleep(2415)
|-tail(1449)
`-udevd(415)-+-udevd(1218)
`-udevd(1219)
(ログアウトする)
再ログインしてジョブが実行中であることを確認
# jobs -l
(バックグラウンドで動いていると思いきや何も表示されない)
# ps aux | grep sleep | grep -v grep
root 2415 0.0 0.0 4072 516 ? S 02:01 0:00 sleep 3600
(psコマンドで確認すると動いてはいるみたい。しかしTTYが?に変わっている)
# pstree -p
init(1)-+-auditd(1033)---{auditd}(1034)
|-crond(1193)
|-master(1183)-+-pickup(1875)
| `-qmgr(1190)
|-mingetty(1206)
|-mingetty(1208)
|-mingetty(1210)
|-mingetty(1212)
|-mingetty(1217)
|-mingetty(1221)
|-ntpd(1107)
|-rsyslogd(1049)-+-{rsyslogd}(1050)
| |-{rsyslogd}(1052)
| `-{rsyslogd}(1053)
|-sleep(2415) ※
|-sshd(1099)-+-sshd(2420)---sshd(2423)---bash(2424)---su(2532)---bash(2536)---watch(2671)
| `-sshd(2945)---sshd(2948)---bash(2949)---su(3064)---bash(3072)---pstree(3232)
|-tail(1449)
`-udevd(415)-+-udevd(1218)
`-udevd(1219)
※ログアウトしたときに親プロセスがなくなったため、initプロセス直下にぶら下がって実行されている
参考
http://kazmax.zpp.jp/linux_beginner/jobs_fg_bg.html
http://kazmax.zpp.jp/linux_beginner/nohup.html
http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230804/
http://d.hatena.ne.jp/satake7/20080606/p1
[bash]シェルからログアウト時にSIGHUP送信する
