Bashスクリプト:開始
Bashスクリプト、パート2:ループ
Bashスクリプト、パート3:オプションとコマンドラインスイッチ
Bashスクリプト、パート4:入力と出力
Bashスクリプト、パート5:シグナル、バックグラウンドタスク、スクリプト管理
Bashスクリプト、パート6:関数とライブラリーの開発
Bashスクリプト、パート7:sedとワープロ
Bashスクリプト、パート8:awkデータ処理言語
Bashスクリプトパート9:正規表現
Bashスクリプト、パート10:ケーススタディ
Bashスクリプト、パート11:対話型ユーティリティの期待と自動化

前回、bashスクリプトの入力、出力、エラーストリーム、ファイル記述子、スレッドリダイレクトの操作について説明しました。 今、あなたはすでにあなた自身を書くのに十分知っています。 bashをマスターするこの段階では、作業スクリプトの管理方法とその起動を自動化する方法について質問があるかもしれません。

これまでのところ、コマンドラインでスクリプト名を入力してEnterキーを押すと、プログラムがすぐに起動しましたが、これがスクリプトを呼び出す唯一の方法ではありません。 今日は、Linuxシグナルでスクリプトがどのように機能するか、作業中にスクリプトを実行してスクリプトを管理するさまざまなアプローチについて説明します。
Linuxシグナル
Linuxでは、システムまたはアプリケーションが生成する30以上のシグナルがあります。 以下に、コマンドラインスクリプトを開発する際に役立つと思われる、最も一般的に使用されるもののリストを示します。
信号コード
| 役職
| 説明
|
1
| シグアップ
| ターミナル閉鎖
|
2
| シギント
| ユーザーは端末からプロセスを停止します(CTRL + C)
|
3
| SIGQUIT
| ユーザーは、メモリダンプを使用して端末(CTRL + \)からプロセスを停止します
|
9
| シグキル
| 無条件のプロセス終了
|
15
| シグターム
| プロセス完了要求信号
|
17
| シグストップ
| プロセスの強制停止、ただしその作業の終了ではない
|
18
| SIGTSTP
| 端末からのプロセスの一時停止(CTRL + Z)、ただしシャットダウンしない
|
19
| SIGCONT
| 以前に停止したプロセスを継続する
|
ターミナルを閉じたときにbashシェルが
SIGHUP
シグナルを受信すると、シャットダウンします。 終了する前に、実行中のスクリプトを含む、実行中のすべてのプロセスに
SIGHUP
シグナルを送信します。
SIGINT
シグナルは一時的なシャットダウンを引き起こします。 Linuxカーネルは、プロセッサー時間をシェルに割り当てなくなります。 これが発生すると、シェルはプロセスに
SIGINT
シグナルを送信して通知します。
Bashスクリプトはこれらのシグナルを制御しませんが、シグナルを認識して特定のコマンドを実行し、シグナルによって引き起こされる結果に備えてスクリプトを準備できます。
スクリプトへのシグナルの送信
bashシェルを使用すると、キーボードショートカットを使用してスクリプトに信号を送信できます。 これは、実行中のスクリプトを一時的に停止したり、作業を終了したりする必要がある場合に非常に役立ちます。
プロセスのシャットダウン
CTRL + C
キーの組み合わせは、
SIGINT
シグナルを生成し、シェルで実行されているすべてのプロセスに送信します。これにより、作業が完了します。
シェルで次のコマンドを実行します。
$ sleep 100
その後、
CTRL + C
キーの組み合わせで作業を完了します
CTRL + C

キーボードのシャットダウン
一時的なプロセスのシャットダウン
CTRL + Z
キーの組み合わせにより、
SIGTSTP
シグナルを生成できます。シグナルはプロセスを一時停止しますが、実行は完了しません。 そのようなプロセスはメモリに残り、その作業を再開できます。 シェルでコマンドを実行します。
$ sleep 100
そして、
CTRL + Z
キーの組み合わせで一時的に停止します。

一時停止プロセス
角括弧内の数字は、シェルがプロセスに割り当てるジョブ番号です。 シェルは、そこで実行されるプロセスを一意の番号を持つタスクと見なします。 最初のプロセスには番号1、2番目のプロセスには2、というように割り当てられます。
シェルにバインドされたタスクを一時停止して終了しようとすると、bashは警告を発行します。
次のコマンドを使用して、中断されたタスクを表示できます。
ps –l

タスクリスト
プロセスの状態を表示する列
S
には、中断されたプロセスの
T
が表示されます。 これは、コマンドが一時停止されているか、トレース状態にあることを示します。
一時停止したプロセスをシャットダウンする必要がある場合は、
kill
コマンドを使用できます。 詳細については、 こちらをご覧ください 。
彼女の呼び出しは次のようになります。
kill processID
信号傍受
スクリプトでLinux信号追跡を有効にするには、
trap
コマンドを使用します。 スクリプトは、このコマンドが呼び出されたときに指定されたシグナルを受け取ると、それを独立して処理しますが、シェルはそのようなシグナルを処理しません。
trap
コマンドは、スクリプトがシグナルに応答できるようにします。そうでない場合、それらの処理はシェルが関与せずにシェルによって実行されます。
trap
コマンドが呼び出されたときに、実行するコードと、インターセプトするスペースで区切られたシグナルのリストがどのように指定されるかを示す例を考えてみましょう。 この場合、これは1つのシグナルにすぎません。
#!/bin/bash trap "echo ' Trapped Ctrl-C'" SIGINT echo This is a test script count=1 while [ $count -le 10 ] do echo "Loop #$count" sleep 1 count=$(( $count + 1 )) done
この例で使用される
trap
コマンドは、キーボードで
Ctrl + C
を押すことで生成できる
SIGINT
シグナルを検出するたびにテキストメッセージを表示します。

信号傍受
CTRL + C
を押すたびに、スクリプトは、シェルを終了させるのではなく、
trace
を呼び出すときに指定された
echo
コマンドを実行します。
スクリプト信号傍受
trap
コマンドを呼び出すときに
EXIT
シグナル名を使用して、スクリプトからの終了シグナルをインターセプトできます。
#!/bin/bash trap "echo Goodbye..." EXIT count=1 while [ $count -le 5 ] do echo "Loop #$count" sleep 1 count=$(( $count + 1 )) done

スクリプト信号傍受
スクリプトを終了するとき、その作業が正常に終了したか、
SIGINT
シグナルによって終了したかにかかわらず、インターセプトは機能し、シェルは
echo
コマンドを実行します。
傍受信号の変更と傍受のキャンセル
スクリプトによってインターセプトされたシグナルを変更するには、新しいパラメーターを使用して
trap
コマンドを実行できます。
#!/bin/bash trap "echo 'Ctrl-C is trapped.'" SIGINT count=1 while [ $count -le 5 ] do echo "Loop #$count" sleep 1 count=$(( $count + 1 )) done trap "echo ' I modified the trap!'" SIGINT count=1 while [ $count -le 5 ] do echo "Second Loop #$count" sleep 1 count=$(( $count + 1 )) done

信号傍受の変更
変更後、信号は新しい方法で処理されます。
シグナルの傍受をキャンセルすることができます。このため、
trap
コマンドを実行し、二重ダッシュとシグナル名を渡すだけで十分です。
#!/bin/bash trap "echo 'Ctrl-C is trapped.'" SIGINT count=1 while [ $count -le 5 ] do echo "Loop #$count" sleep 1 count=$(( $count + 1 )) done trap -- SIGINT echo "I just removed the trap" count=1 while [ $count -le 5 ] do echo "Second Loop #$count" sleep 1 count=$(( $count + 1 )) done
インターセプトがキャンセルされる前にスクリプトが信号を受信した場合、現在の
trap
コマンドで指定された
trap
処理します。 スクリプトを実行します。
$ ./myscript
そして、キーボードの
CTRL + C
を押します。

キャンセル前に傍受された信号
CTRL + C
の最初の押下は、スクリプトが実行されたときに発生し、シグナルインターセプトが有効であったため、スクリプトはシグナルに割り当てられた
echo
コマンドを実行しました。 実行がインターセプトをキャンセルするコマンドに到達した後、
CTRL + C
コマンドは通常の方法で機能し、スクリプトを終了しました。
バックグラウンドでコマンドラインスクリプトを実行する
bashスクリプトがタスクを完了するのに時間がかかる場合があります。 この場合、スクリプトの完了を待たずに、コマンドラインで正常に機能する必要があります。 これを実装することはそれほど難しくありません。
ps
コマンドによって表示されるプロセスのリストを見た場合、バックグラウンドで実行されており、端末に関連付けられていないプロセスに気付く場合があります。
次のようなスクリプトを作成しましょう。
#!/bin/bash count=1 while [ $count -le 10 ] do sleep 1 count=$(( $count + 1 )) done
名前の後にアンパサンド(
&
)文字を指定して実行します。
$ ./myscipt &
これにより、バックグラウンドプロセスとして開始されます。

バックグラウンドでスクリプトを実行する
スクリプトはバックグラウンドプロセスで起動され、その識別子がターミナルに表示され、実行が完了すると、これに関するメッセージが表示されます。
スクリプトはバックグラウンドで実行されますが、ターミナルを使用して
STDOUT
および
STDERR
メッセージを表示し続けることに注意してください。つまり、表示されるテキストまたはエラーメッセージはターミナルで見ることができます。

プロセスリスト
このアプローチでは、ターミナルを終了すると、バックグラウンドで実行されているスクリプトも作業を完了します。
ターミナルを閉じた後でもスクリプトが動作し続ける必要がある場合はどうなりますか?
ターミナルを閉じるときに終了しないスクリプトの実行
スクリプトは、ターミナルセッションを終了した後でもバックグラウンドプロセスで実行できます。 これを行うには、
nohup
コマンドを使用できます。 このコマンドを使用すると、プロセスに送信される
SIGHUP
シグナルをブロックして、プログラムを開始できます。 その結果、プロセスは、それが開始された端末を離れる場合でも実行されます。
スクリプトを実行するときにこの手法を適用します。
nohup ./myscript &
これは端末に出力されるものです。

ノーフチーム
nohup
コマンドは、端末からプロセスのバインドを解除します。 これは、プロセスが
STDOUT
および
STDERR
への参照を失うことを意味し
STDOUT
。 スクリプトによるデータ出力が失われないように、
nohup
は
STDOUT
および
STDERR
に到着するメッセージをファイル
nohup.out
自動的にリダイレクトします。
同じディレクトリから複数のスクリプトを実行すると、それらの出力は1つの
nohup.out
ファイルに分類されることに注意してください。
課題を見る
jobs
コマンドを使用すると、シェルで実行されている現在のジョブを表示できます。 次のようなスクリプトを作成しましょう。
#!/bin/bash count=1 while [ $count -le 10 ] do echo "Loop #$count" sleep 10 count=$(( $count + 1 )) done
実行してください:
$ ./myscript
そして、キーの組み合わせ
CTRL + Z
一時的に停止します。

スクリプトの実行と一時停止
画面に何も表示されないように、スクリプト出力をファイルにリダイレクトしながら、バックグラウンドで同じスクリプトを実行します。
$ ./myscript > outfile &
jobs
コマンドが完了すると、中断されたスクリプトとバックグラウンドで動作するスクリプトの両方に関する情報が表示されます。

スクリプト情報の取得
jobs
コマンドを呼び出すときの
-l
スイッチは、プロセス
ID
に関する情報が必要であることを示します。
一時停止したジョブを再開する
バックグラウンドでスクリプトを再起動するには、
bg
コマンドを使用できます。
スクリプトを実行します。
$ ./myscript
CTRL + Z
押すと、実行が一時的に停止します。 次のコマンドを実行します。
$ bg

BGコマンド
これで、スクリプトはバックグラウンドで実行されます。
複数の一時停止ジョブがある場合、
bg
番号を渡して特定のジョブを再開できます。
タスクを通常モードで再起動するには、
fg
コマンドを使用します。
$ fg 1
スクリプトを実行する計画
Linuxには、特定の時間にbashスクリプトを実行する方法がいくつかあります。 これは
at
コマンドと
cron
ジョブスケジューラです。
atへの呼び出しは次のようになります。
at [-f filename] time
このコマンドは、多くの時間形式を認識します。
- 標準、時間と分、たとえば-10:15。
- AM / PMインジケータを使用して、正午前後に、たとえば午後10時15分。
-
now
、noon
、midnight
ような特別な名前を使用します。
タスクの開始時刻を指定する機能に加えて、
at
コマンドには、サポートされている形式のいずれかを使用して日付を指定することもできます。
- テンプレート
MMDDYY
、MM/DD/YY
、またはDD.MM.YY
を使用して日付が記録される日付を示すための標準形式。 - 日付のテキスト表現。たとえば、
Jul 4
やDec 25
など。年は指定できますが、年を指定しなくてもかまいません。 -
now + 25 minutes
ようなレコードnow + 25 minutes
。 -
10:15PM tomorrow
ビューを記録します。 - フォーム
10:15 + 7 days
。
このトピックについては詳しく説明しませんが、コマンドの簡単な使用例を考えてみましょう。
$ at -f ./myscript now

atコマンドを使用したタスクのスケジューリング
at
呼び出すときの
-M
at
、システムが適切に構成されている場合にスクリプトが出力する内容を電子メールで送信するために使用されます。 電子メールを送信できない場合、このキーは単に出力を抑制します。
完了待ちのタスクのリストを表示するには、
atq
コマンドを使用できます。
$ atq

保留中のジョブのリスト
保留中のジョブの削除
atrm
コマンドを使用すると
atrm
を
atrm
できます。 呼び出されると、タスク番号が示されます。
$ atrm 18

ジョブを削除
スケジュールされたスクリプト
at
コマンドを使用して1回限りのスクリプト実行を計画すると、多くの状況で作業が楽になります。 しかし、毎日同じ時間に、または週に1回、または月に1回、スクリプトを実行する場合はどうでしょうか。
Linuxには、スクリプトを定期的に実行するようにスケジュールできる
crontab
ユーティリティがあります。
Crontab
はバックグラウンドで実行され、いわゆるcronテーブルのデータに基づいて、スケジュールされたジョブを実行します。
既存の
cron
ジョブテーブルを表示するには、次のコマンドを使用します。
$ crontab –l
スケジュールに基づいてスクリプトを実行することを計画している場合、
crontab
は次の形式でタスクをいつ完了するかに関するデータを受け取ります。
, , , , .
たとえば、
command
と呼ばれる特定のスクリプトを毎日10:30に実行
command
、これはタスクテーブルのそのようなエントリに対応します。
30 10 * * * command
ここで、月、月、曜日を指定するフィールドに使用されるユニバーサルシンボル「
*
」は、
cron
が毎月10:30にコマンドを実行することを示します。
たとえば、毎週月曜日の
4:30PM
スクリプトを実行する場合は、タスクテーブルに次のエントリを作成する必要があります。
30 16 * * 1 command
曜日の番号は0で始まり、0は日曜日、6は土曜日を意味します。 別の例を示します。 ここでは、コマンドは毎月1日の正午に実行されます。
00 12 1 * * command
月の番号は1から始まります。
テーブルにエントリを追加するには、
-e
スイッチを
-e
して
crontab
を呼び出す必要があります。
crontab –e
次に、スケジュール生成コマンドを入力できます。
30 10 * * * /home/likegeeks/Desktop/myscript
このコマンドのおかげで、スクリプトは毎日10:30に呼び出されます。 「リソースが一時的に利用できません」というエラーが発生した場合は、ルート権限で次のコマンドを実行します。
$ rm -f /var/run/crond.pid
いくつかの特別なディレクトリを使用して、
cron
を使用してスクリプトの定期的な起動を整理するのがさらに簡単です。
/etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly
スクリプトファイルをそれらの1つに配置すると、それぞれ、毎時、毎日、毎週、または毎月の起動につながります。
ログインおよびシェルの起動時に実行されるスクリプト
ユーザーのログインやシェルの起動など、さまざまなイベントに基づいてスクリプトの起動を自動化できます。 ここでは、そのような状況で処理されるファイルについて読むことができます。 たとえば、これらは次のファイルです。
$HOME/.bash_profile $HOME/.bash_login $HOME/.profile
ログイン時にスクリプトを実行するには、その呼び出しを
.bash_profile
ファイルに入れます。
ターミナルを開くときにスクリプトを実行するのはどうですか?
.bashrc
ファイルは、これを整理するのに役立ちます。
まとめ
今日は、スクリプトのライフサイクル管理に関連する問題を調査し、バックグラウンドでスクリプトを実行する方法と、スケジュールに従って実行を計画する方法について説明しました。 次回は、bashスクリプトの機能とライブラリ開発について読んでください。
親愛なる読者! スケジュールされたスケジューリングコマンドラインスクリプトを使用していますか? もしそうなら、それらについて教えてください。
