linux – ジョブのバックグラウンド実行

以下手順で行います。
- プロセスを実行
ctrl + z
で中断する。bg
コマンドでプロセスをバックグラウンドに移す。
# sleepで実験
sleep 10
# ctrl + zで中断
^Z
[1]+ Stopped sleep 10
# jobを確認
jobs
[1]+ Stopped sleep 10
# bgコマンドでjobをバックグラウンド実行
# bg [job ID]
bg 1
[1]+ sleep 10 &
# 実行終了すると、以下が出力される
[1]+ Done sleep 10
コンソール出力のあるプロセスのバックグラウンド実行
ping
など、コンソールに実行結果が帰ってくるプロセスだと、バックグラウンドで実行していても、コンソールに結果が出力されるため、うまくいかない。
そのため、コンソールの出力を捨てる必要がある。
# pingで実験してみる
ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=2.50 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=4.76 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=1.46 ms
64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=1.51 ms
# ctrl + zで中断
^Z
[1]+ Stopped ping 192.168.1.1
# バックグラウンド実行
bg 1
[1]+ ping 192.168.1.1 &
# コンソールに結果が出力されて、まともにコマンドも打ちにくくなる
[email protected]:~ $ 64 bytes from 192.168.1.1: icmp_seq=5 ttl=64 time=2.04 ms
64 bytes from 192.168.1.1: icmp_seq=6 ttl=64 time=1.79 ms
64 bytes from 192.168.1.1: icmp_seq=7 ttl=64 time=1.47 ms
64 bytes from 192.168.1.1: icmp_seq=8 ttl=64 time=1.38 ms
64 bytes from 192.168.1.1: icmp_seq=9 ttl=64 time=1.46 ms
64 bytes from 192.168.1.1: icmp_seq=10 ttl=64 time=3.85 ms
64 bytes from 192.168.1.1: icmp_seq=11 ttl=64 time=2.66 ms
ちなみに、この状態でping
を止めようとして、ctrl + c
を実行しても、止まりません。コンソールに出力され続けていますが、ping
がバックグラウンドで実行されているためです。この場合、ping
をフォアグラウンドに戻す必要があります。フォアグラウンドに戻す場合、fg
コマンドで行います。
# pingを実行
ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.50 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.50 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=1.54 ms
# ctrl + z で中断
^Z
[1]+ Stopped ping 192.168.1.1
# bgコマンドでバックグラウンド実行
[email protected]:~ $ bg 1
[1]+ ping 192.168.1.1 &
# バックグラウンド実行ではあるが、コンソールに結果が出力される
[email protected]:~ $ 64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=1.61 ms
64 bytes from 192.168.1.1: icmp_seq=5 ttl=64 time=1.49 ms
64 bytes from 192.168.1.1: icmp_seq=6 ttl=64 time=1.43 ms
64 bytes from 192.168.1.1: icmp_seq=7 ttl=64 time=1.58 ms
64 bytes from 192.168.1.1: icmp_seq=8 ttl=64 time=1.50 ms
# fgコマンドでpingをフォアグラウンドにする
fg 1
# pingがフォアグラウンドで実行される
ping 192.168.1.1
64 bytes from 192.168.1.1: icmp_seq=10 ttl=64 time=1.75 ms
64 bytes from 192.168.1.1: icmp_seq=11 ttl=64 time=1.49 ms
64 bytes from 192.168.1.1: icmp_seq=12 ttl=64 time=2.68 ms
# ctrl + c で終了させる
^C
--- 192.168.1.1 ping statistics ---
12 packets transmitted, 12 received, 0% packet loss, time 15380ms
rtt min/avg/max/mdev = 1.430/1.629/2.687/0.332 ms
こういう場合は、バックグラウンド時に結果をコンソールに出力されないよう、/dev/null
に出力結果をリダイレクトします。
# pingを/dev/nullにリダイレクト
ping 192.168.1.1 > /dev/null
# ctrl + zで中断
^Z
[1]+ Stopped ping 192.168.1.1 > /dev/null
# バックグラウンド実行
bg 1
[1]+ ping 192.168.1.1 > /dev/null &
# jobを確認
jobs
[1]+ Running ping 192.168.1.1 > /dev/null &
結果を捨てないように、リダイレクトでファイルに出力する場合も、上記と同様にコンソールに結果は出力されないようになります。適宜使い分けます。
ping
では実用性なさそうですが、参考までに。
プロセスの起動確認
一旦コンソールからログアウトしてしまうと、jobs
コマンドでバックグラウンドで実行中のコマンドが確認できなくなります。その場合は、ps
コマンドでプロセスを確認します。引数aux
を使う場合は、grep
などで絞り込むほうが目的のものも見つけやすくなります。
ps aux | grep ping
user 14932 0.0 0.0 4928 680 pts/0 S 18:10 0:00 ping 192.168.1.1
ps
の引数
* a
– 自分以外のユーザ全てのプロセスを表示
* u
– ユーザ名と開始時間を表示
* x
– デーモンを表示
バックグラウンドにすると動かなくなるjob
バックグラウンド実行するとjobがStopped
のままで、フォアグラウンドに戻すとRunning
になるようなjobは、入力待ちになってしまっている可能性があります。
その場合、標準入力に/dev/null
を与えてあげる必要があります。
仮に、そのようなjobをsample.sh
とすると、以下のように実行し、その後バックグラウンド実行にします。
# 標準入力に/dev/nullを与えて実行
bash sample.sh </dev/null
# 中断する
ctrl + z
# バックグラウンド実行する
bg