バックグラウンド操作


スクリプトをバックグラウンドで実行する機会があったんだけど、バックグラウンドで実行するジョブの操作など、全く理解していなかったので備忘録。

■バックグラウンドでコマンドを実行する

構文 説明
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番号 ジョブ番号を指定しない場合はカレントジョブが実行される

[手順]

  1. Ctrl + zキーでジョブを一時停止
  2. 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送信する