Linux バックグラウンド実行

LinuxBeginner
オンラインで実践に進む

はじめに

Linux はプロセス管理のための強力な機能を提供しており、ユーザーはターミナルで作業を続けながらコマンドをバックグラウンドで実行できます。この機能は、常に監視を必要としない時間のかかるタスクを扱う際に不可欠です。この実験 (Lab) では、プロセスをバックグラウンドで実行する方法、そのステータスを確認する方法、そしてそれらを効果的に管理する方法を学びます。これらのスキルは、あらゆる Linux ユーザーにとって基本的であり、コマンドライン環境で作業する際の柔軟性を高めます。

バックグラウンドプロセスの理解

Linux では、プロセスはフォアグラウンドまたはバックグラウンドで実行できます。フォアグラウンドプロセスは、完了するまでターミナルを占有し、他のコマンドの実行を妨げます。一方、バックグラウンドプロセスは、ターミナルをブロックすることなく実行され、コマンドラインの使用を継続できます。

まず、長時間実行されるタスクをシミュレートする簡単なスクリプトを作成しましょう。これはバックグラウンドプロセスのデモンストレーションに役立ちます。

プロジェクトディレクトリに移動します。

cd ~/project

nano エディタを使用して long-task.sh という名前のファイルを作成します。

nano long-task.sh

ファイルに以下の内容を追加します。

#!/bin/bash
## This script simulates a long-running task
echo "Starting long task..."
for i in {1..20}; do
  echo "Processing step $i..."
  sleep 5
done
echo "Long task completed."

ファイルを保存するために Ctrl+O を押し、次に Enter を押し、nano を終了するために Ctrl+X を押します。

スクリプトのパーミッションを変更して実行可能にします。

chmod +x long-task.sh

次に、スクリプトをフォアグラウンドで実行します。

./long-task.sh

スクリプトは 5 秒の遅延とともに各ステップの出力を表示します。この間、プロセスがフォアグラウンドで実行されているため、ターミナルに他のコマンドを入力できないことに注意してください。

スクリプトが完了する前に終了するには Ctrl+C を押します。

バックグラウンドでのプロセス実行

プロセスをバックグラウンドで実行するには、コマンドの末尾にアンパサンド (&) を追加するだけです。これにより、シェルはそのコマンドをバックグラウンドで実行するように指示されます。

long-task.sh スクリプトをバックグラウンドで実行してみましょう。

cd ~/project
./long-task.sh &

以下のような出力が表示されるはずです。

[1] 1234
Starting long task...
Processing step 1...

ここで、[1] はシェルによって割り当てられたジョブ番号であり、1234 はプロセス ID (PID) です。ジョブ番号は、シェル内でこのバックグラウンドプロセスを参照するために使用され、PID はオペレーティングシステムがプロセスを識別するために使用します。

最初の出力の後、コマンドプロンプトが戻ってくることに注意してください。スクリプトがバックグラウンドで実行されている間、他のコマンドを入力し続けることができます。

例えば、別のファイルを作成してみましょう。

echo "I can do other work while the script runs" > background-demo.txt
cat background-demo.txt

バックグラウンドスクリプトからの出力が時折表示されながらも、ターミナルで作業を続けられることがわかります。これは、ターミナルセッションをブロックすることなく、時間のかかるタスクを実行するのに非常に役立ちます。

重要な注意点: バックグラウンドプロセスの出力がターミナルに表示されるのは完全に正常です。& を使用してプロセスをバックグラウンドで実行すると、プロセスはバックグラウンドで実行されますが、その出力ストリーム (stdout および stderr) は引き続きターミナルに接続されています。これは次のことを意味します。

  • プロセスはバックグラウンドで実行されています (他のコマンドを入力できます)。
  • プロセスはターミナルをブロックすることなく実行を継続します。
  • 出力は画面に表示され続けます (他のコマンドと混ざる可能性があります)。

この動作は予期されたものであり、バックグラウンドプロセスがアクティブに実行され、出力を生成していることを示しています。

バックグラウンドプロセスの確認

Linux には、バックグラウンドで実行されているプロセスを確認するためのいくつかのコマンドがあります。最も一般的なのは jobsps です。

jobs コマンドの使用

jobs コマンドは、現在のシェルセッションにおけるすべてのバックグラウンドジョブのステータスを表示します。

jobs

以下のような出力が表示されるはずです。

[1]+  Running    ./long-task.sh &

+ 記号は、これが現在のデフォルトジョブであることを示します。これは、ジョブ番号を指定せずに fgbg のようなコマンドを使用した場合に操作されるジョブであることを意味します。

ps コマンドの使用

jobs は現在のシェルから開始されたプロセスのみを表示しますが、ps コマンドはシステムで実行されているすべてのプロセスを表示できます。

ps aux | grep long-task.sh

出力には、バックグラウンドスクリプトの行が含まれるはずです。

labex     1234  0.0  0.0   4508  1996 pts/0    S    12:34   0:00 /bin/bash ./long-task.sh

複数のジョブを確認できるように、別のバックグラウンドプロセスを作成しましょう。

cd ~/project
nano another-task.sh

以下の内容を追加します。

#!/bin/bash
## This script simulates another task
echo "Starting another task..."
for i in {1..20}; do
  echo "Another task - step $i..."
  sleep 5
done
echo "Another task completed."

nano を保存して終了し (Ctrl+O、Enter、Ctrl+X)、スクリプトを実行可能にします。

chmod +x another-task.sh

このスクリプトもバックグラウンドで実行します。

./another-task.sh &

再度バックグラウンドジョブを確認します。

jobs

両方のジョブがリストされているはずです。

[1]-  Running    ./long-task.sh &
[2]+  Running    ./another-task.sh &

バックグラウンドプロセスの管理

バックグラウンドでプロセスを実行できるようになったので、それらを管理する方法を学びましょう。Linux には、バックグラウンドプロセスを制御するためのいくつかのコマンドがあります。

バックグラウンドプロセスをフォアグラウンドに移動する

fg コマンドは、バックグラウンドプロセスをフォアグラウンドに移動させます。複数のバックグラウンドジョブがある場合、ジョブ番号を使用してどのジョブを移動させるかを指定できます。

最初のジョブをフォアグラウンドに移動させてみましょう。

fg %1

%1 はジョブ番号 1 を参照します。long-task.sh スクリプトの出力がターミナルに表示され、プロセスが完了するか停止するまでコマンドプロンプトは使用できなくなります。

プロセスを中断してコマンドプロンプトに戻るには、Ctrl+C を押します。

フォアグラウンドプロセスをバックグラウンドに送る

フォアグラウンドプロセスをバックグラウンドに送ることもできます。まず、Ctrl+Z でフォアグラウンドプロセスを一時停止し、次に bg コマンドを使用してバックグラウンドで続行します。

新しいフォアグラウンドプロセスを開始します。

cd ~/project
./long-task.sh

数秒後、Ctrl+Z を押してプロセスを一時停止します。以下のようなメッセージが表示されます。

[1]+  Stopped    ./long-task.sh

次に、バックグラウンドで続行します。

bg

プロセスはバックグラウンドで実行を再開し、以下のように表示されます。

[1]+ ./long-task.sh &

実行中であることを確認するには、次のようにします。

jobs

バックグラウンドプロセスの終了

バックグラウンドプロセスを終了するには、ジョブ番号またはプロセス ID を使用して kill コマンドを使用できます。

kill %1

または PID を使用して (実際の PID は ps の出力から置き換えてください):

kill 1234

プロセスが終了したことを確認するには、次のようにします。

jobs

ジョブが終了したことを示すメッセージが表示される場合があります。

[1]+  Terminated    ./long-task.sh

ログアウト後もプロセスを実行する

ターミナルからログアウトした後もプロセスを実行し続けたい場合があります。nohup コマンドを使用すると、シェルを終了した後も実行を継続するコマンドを実行できます。

長時間実行されるスクリプトを作成しましょう。

cd ~/project
nano persistent-task.sh

以下の内容を追加します。

#!/bin/bash
## This script runs for a very long time
echo "Starting persistent task at $(date)" > persistent-output.log
for i in {1..100}; do
  echo "Iteration $i at $(date)" >> persistent-output.log
  sleep 10
done
echo "Persistent task completed at $(date)" >> persistent-output.log

nano を保存して終了し、スクリプトを実行可能にします。

chmod +x persistent-task.sh

次に、nohup で実行し、バックグラウンドに配置します。

nohup ./persistent-task.sh &

以下のような出力が表示されます。

[1] 5678
nohup: ignoring input and appending output to 'nohup.out'

これは、プロセスがバックグラウンドで実行されており、ログアウトしても継続されることを意味します。通常ターミナルに表示される出力は、nohup.out というファイルにリダイレクトされます。

出力管理のヒント: バックグラウンドプロセスの出力がターミナルに表示され、作業の妨げになるのを避けたい場合は、出力をファイルにリダイレクトできます。

## 出力を特定のファイルにリダイレクトする
./long-task.sh > task-output.log 2>&1 &

## または、出力を完全に破棄するために /dev/null にリダイレクトする
./long-task.sh > /dev/null 2>&1 &

2>&1 は標準出力とエラー出力を両方リダイレクトします。これにより、バックグラウンドプロセスはターミナルを煩雑にすることなく、静かに実行されます。

プロセスが実行されているか確認できます。

ps aux | grep persistent-task.sh

出力ファイルを確認できます。

cat persistent-output.log

出力には、永続タスクの開始時刻とイテレーションが表示されます。

disown コマンド

ログアウト後もプロセスを実行し続けるもう一つの方法は、disown コマンドを使用することです。まず、プロセスをバックグラウンドで実行します。

cd ~/project
./persistent-task.sh &

次に disown を使用して、ターミナルから切り離します。

disown %1

これで、ターミナルを閉じてもこのプロセスは実行を継続します。

これらのコマンドは、リモートサーバーでプロセスを切断後も継続させる必要がある場合に不可欠です。

まとめ

この実験では、バックグラウンドプロセスの管理に不可欠な Linux スキルを学びました。以下のことを実践しました。

  1. フォアグラウンドモードとバックグラウンドモードの両方でスクリプトを作成および実行する
  2. & オペレーターを使用してプロセスをバックグラウンドで実行する
  3. jobs および ps を使用してバックグラウンドプロセスのステータスを確認する
  4. fg および bg コマンドを使用してプロセスをフォアグラウンドとバックグラウンド間で移動させて管理する
  5. kill コマンドを使用してバックグラウンドプロセスを終了する
  6. nohup および disown を使用してログアウト後も継続するプロセスを実行する

これらのスキルは、特に長時間実行されるタスクを扱ったり、リモートサーバーで作業したりする場合に、Linux 環境で効率的に作業するための基本となります。プロセスをバックグラウンドで実行することにより、ターミナルセッションをブロックすることなく複数のタスクを同時に実行することで、生産性を最大化できます。