Tera Termマクロを作成しているとき、「処理の途中で少し待たせたい」「サーバー側の処理が終わるのを待ってから次のコマンドを送りたい」と思ったことはないでしょうか。マクロの記述において、処理を止めるコマンドとしてよく使われるのが pause と wait です。
しかし、「なんとなくどちらを使っても同じように止まる気がする」「なぜか処理がスキップされてしまう」といった疑問やトラブルに直面するエンジニアも少なくありません。
この記事では、pause コマンドと wait コマンドの決定的な違いと正しい使い分けを解説します。意図しないタイムアウトや処理の抜けを防ぎ、堅牢な自動化スクリプトを作成できるようになりましょう。
確認した環境は以下の通りです。
- OSOS [オーエス]Operating System。基本ソフトウェア: Windows 11 (64bit)
- ターミナルエミュレータ: Tera Term (Version 4.107 / Version 5.x)
- 対象サーバー: UbuntuUbuntu [ウブントゥ]人気のLinuxディストリビューション 24.04 LTS, Rocky LinuxLinux [リナックス / ライナックス]オープンソースのOSカーネル 9
Tera Termマクロにおけるpauseとwaitの基本的な違い
Tera Termマクロで処理を停止させる際、pause と wait は全く異なる目的で作られています。
pause: 時間を基準にして、指定した秒数だけマクロの実行を無条件に休止します。wait: ホスト(リモートサーバー)から受信した文字列を基準にして、特定の文字列を受信するまでマクロの処理を待機します。
ネットワーク機器やLinuxサーバーへの設定投入自動化では、サーバー側の処理速度にばらつきが生じます。そのため、時間の経過だけを待つ pause よりも、サーバーからの応答を確認できる wait などの待機コマンドを適切に組み合わせることが重要になります。なお、指定文字列を受信したこと自体はコマンドの実行成功を意味するわけではない点にも注意が必要です。
pauseコマンドの使い方:指定秒数の休止とmpauseの活用
pause は、マクロの実行を指定した秒数だけ休止するコマンドです。次のコマンドを送信するまでに一定の間隔を設けたい場合などに利用できます。ただし、pause 自体がサーバーへの負荷を軽減するわけではなく、画面描画やサーバー側の処理が完了したことも確認しません。
pause・mpauseの基本構文とコード例
pause の構文は非常にシンプルで、引数に停止させたい秒数を指定します。ミリ秒単位で指定したい場合は mpause(Tera Term 4.27以降)を使います。
; 3秒間マクロの実行を休止するpause 3
; 500ミリ秒(0.5秒)休止する場合は mpause を使用mpause 500実務のスクリプトでは、キー入力を連続して送信したくない場面や、コマンド送信の間に一定の間隔をあけたい補助的な用途で使用されます。
connect "192.168.1.10:22 /ssh /2 /user=admin /passwd=secret"
; ログイン完了後のシェルプロンプトを待つwait "$" "#"
; コマンド送信前に少しだけ間隔を空けたい場合の例pause 1sendln "uptime"※接続直後に pause 2 などを置いて待つコードを見かけることがありますが、pause は接続処理やログイン処理の完了を保証するものではありません。ログイン完了の確認には、必ず後述する wait などの待機コマンドを使用してください。
pauseの注意点:サーバーの処理完了を待てない理由
pause はサーバーの状態を一切確認していません。そのため、サーバー側が何らかの原因で重くなっており、指定した秒数以内に処理が終わらなかった場合でも、容赦なく次のコマンドが送信されてしまいます。結果として、前の処理が終わる前に後続の処理へ進んでしまい、想定外の動作になるトラブルの原因になります。
waitコマンドの使い方:ホストからの文字列受信を待機する
wait は、ホストから指定した文字列を受信するまでマクロの実行を待機させるコマンドです。複数の文字列を指定することもでき、いずれかの文字列を受信すると待機を終了します。なお、指定文字列を受信したことは、コマンドの実行成功を意味するわけではありません。
waitの基本構文と複数文字列・正規表現の指定方法
wait コマンドの一般的な構文は以下の通りです。文字列をダブルクォーテーション(またはシングルクォーテーション)で囲んで指定します。
; "Password:" という文字列を受信するまで待機するwait "Password:"wait コマンドは、1回の呼び出しで最大10個まで文字列を指定でき、そのうちいずれかを受信すると待機を終了します。どの文字列に一致したかは、システム変数 result に格納されます(詳細は後述)。
また、正規表現で待機したい場合は waitregex(Tera Term 4.21以降)、行末まで含めて行単位で待ちたい場合は waitln も選択肢になります。
connect "192.168.1.10:22 /ssh /2 /user=admin /passwd=secret"
; ログイン後のシェルプロンプトを受信するのを待つ; ※ "$" や "#" などの1文字だけで待機すると、コマンド出力や他のメッセージに含まれる記号に誤一致するリスクがあります。; 実運用では、環境固有のプロンプト(例: "user@server:~$")を指定することが推奨されます。wait "user@server:~$" "root@server:~#"waitコマンドの主な特徴(動的な待機と柔軟性)
- 動的な待機: サーバーの処理が早く終われば即座に次の処理へ移行し、遅ければ完了するまでしっかりと待機します。
- 柔軟性: プロンプト文字列だけでなく、パスワード要求や特定のエラーメッセージを検知して分岐させることができます。
pauseとwaitの正しい使い分けと実践トラブル対策
実際の運用スクリプトでは、pause と wait をどのように使い分ければよいのでしょうか。基本方針としては、**「サーバーの応答を確認する必要がある場合は、wait などの待機コマンドを使い、純粋な入力間隔調整などの特殊な場面でのみ pause(または mpause)を使う」**ことになります。
ここでは、実務でよくあるトラブルとその対策を解説します。
【失敗例】pauseだけでコマンドを連続送信してはいけない理由
よくある失敗として、wait を使わずに sendln と pause だけを並べてしまうケースがあります。
; 【避けるべき書き方】sendln "sudo apt update"pause 5sendln "sudo apt upgrade -y"この書き方では、apt update が完了したかどうかを一切確認していません。5秒以内に終わらなかった場合でも次のコマンドが送信され、sudo のパスワード入力待ちに入力が食われたり、出力が混在して処理結果を判別できなくなったりします。「完了してから次へ進む」ことを保証できない点が根本的な問題です。
プロンプト待機・sudoパスワード要求を安全に処理する書き方
それでは、単に wait "$" や wait "#" を置けば万全かというと、それだけでは実務向けの推奨例としては不十分です。例えば、sudo のパスワード要求が発生した場合や、途中でエラーが発生した場合でも、待機文字列への一致によって誤って次の処理に進んでしまう可能性があります。
実務スクリプトでは、シェルプロンプトとパスワード要求を区別し、タイムアウトや例外を適切にハンドリングする構造にします。
以下は、sudo apt update の実行後に sudosudo [スードゥー / スーデュー]Superuser doの略。一時的に他のユーザー(主に管理者特権)の権限でコマンドを実行する のパスワード要求、またはシェルプロンプトを待つ例です。
; タイムアウトを30秒に設定timeout = 30mtimeout = 0
; コマンドを送信sendln "sudo apt update"
; sudoのパスワード要求、またはシェルプロンプトを待つ; ※パスワード要求の表示形式やシェルプロンプト(user@server:~$)は環境によって異なるため、; 実際の対象サーバーに合わせて文字列を変更してください。wait "Password:" "user@server:~$"
if result = 0 then messagebox "応答がタイムアウトしました。" "エラー" endelseif result = 1 then ; パスワード要求への対応が必要 messagebox "パスワード入力が必要です。" "確認" endelseif result = 2 then ; シェルプロンプトを受信 ; ただし、コマンド自体の成否までは保証されないendifコマンド成否の判定とエコーバック誤検知の対策
上記の例でシェルプロンプトを受信できたとしても、それは「コマンドの実行が終わり、シェルに入力できる状態に戻った」ことしか示しておらず、apt update が正常終了したか異常終了したかまでは判別できません。
コマンドの成否まで自動判定したい場合は、シェル側で終了コードを判定させ、マクロ側で捕捉しやすい専用のマーカー文字列を出力させる方法が確実です。
ただし、ここで非常に重要な落とし穴があります。Tera Termでは、sendln で送信したコマンド文字列がサーバーからそのまま画面へエコーバック(跳ね返り)されます。もし echo __CMD_SUCCESS__ のように送信コマンドの中に完成形のマーカー文字列を含めてしまうと、コマンドの実行完了を待つ前に、送信したコマンド自体のエコーバックに wait がヒットして誤通過してしまうのです。
これを防ぐには、送信コマンド内に完成形のマーカー文字列を含めず、シェル側の printf などの書式指定を使って実行時にマーカーを動的生成させます。また、マーカー受信後には次のコマンドを安全に受け付けるため、シェルプロンプトへの復帰まで確認するのが堅牢な書き方です。
; 更新処理に合わせてタイムアウトを長め(120秒)に設定timeout = 120mtimeout = 0
; エコーバックによる誤判定を防ぐため、printf で完成形マーカーを動的に生成するsendln "if sudo apt update; then printf '__CMD_%s__\n' SUCCESS; else printf '__CMD_%s__\n' FAILED; fi"
; マーカー文字列の出力を待つwait "__CMD_SUCCESS__" "__CMD_FAILED__"
if result = 0 then messagebox "コマンドの応答がタイムアウトしました。" "エラー" endelseif result = 1 then ; 正常終了時の処理elseif result = 2 then ; 異常終了時のエラーハンドリング messagebox "apt update が失敗しました。処理を中断します。" "エラー" endendif
; マーカー受信後、シェルプロンプトへの復帰を確認して後続処理の安全を確保するwait "user@server:~$" "root@server:~#"if result = 0 then messagebox "シェルプロンプトへの復帰がタイムアウトしました。" "エラー" endendif※なお、sudo のパスワード入力が必要な環境では、事前に認証が済んでいる(タイムスタンプが有効な)状態にしておくか、前述のパスワード分岐処理と組み合わせる必要があります。
受信バッファ破棄(flushrecv)の注意点と誤用リスク
古いプロンプトなどが受信バッファに残っていると、wait が古い文字列を検知して即座に通過してしまうことがあります。
Tera Termには受信バッファに残っている文字を破棄する flushrecv コマンドが用意されています。しかし、flushrecv は送信後に届いた未処理の応答まで破棄してしまう危険性があります。
そのため、「とりあえずコマンド送信前に毎回入れる」といった無条件の使用は危険です。古い受信データが原因だと確認でき、破棄しても後続処理に影響がないタイミングに限定して使用してください。
タイムアウト(timeout/mtimeout)とresultで安全に待機する方法
wait コマンドは非常に便利ですが、もしサーバー側でフリーズが発生したり、予期せぬプロンプトの変化によって目的の文字列が表示されなかった場合、マクロが永遠にその場で停止(ハングアップ)してしまいます。
これを防ぐために不可欠なのが、timeout システム変数との組み合わせです。
timeout・mtimeout変数による待機時間の設定
Tera Termマクロでは、システム変数 timeout(秒単位)や mtimeout(ミリ秒単位)に数値を代入することで、wait コマンドが指定時間内に目的の文字列を検知できなかった場合のタイムアウト時間を設定できます。
timeoutに秒、mtimeoutにミリ秒を設定すると、両者を組み合わせた時間(<timeout>.<mtimeout>秒)が待機時間の上限になります。- どちらか一方が正の値であればタイムアウトが有効になります(例:
timeout = 0かつmtimeout = 500の場合は0.5秒でタイムアウト)。 timeoutとmtimeoutの両方が0以下の場合にのみ、タイムアウトは発生せず無期限に待機します。- 一度設定した
timeoutやmtimeoutの値は、以降に実行されるすべての待機コマンドに影響します。特定コマンドでのみタイムアウトを変更したい場合は、処理後に元の値へリセットしてください。
; タイムアウトを10秒に設定(ミリ秒は0にクリア)timeout = 10mtimeout = 0
sendln "systemctl restart nginx"
; コマンド実行後にプロンプトが表示されるのを待つ; ※実際の環境に合わせたプロンプト文字列を指定しますwait "user@server:~$" "root@server:~#"
if result = 0 then ; resultが0の場合、指定文字列を受信できずにタイムアウトしたことを意味する messagebox "タイムアウトが発生しました。処理を中断します。" "エラー" endelse ; resultが1以上の場合、指定文字列を受信した messagebox "プロンプトを受信しました。" "完了"endifシステム変数resultによるタイムアウト検知と条件分岐
wait コマンドが実行された後、システム変数 result には以下のような値が格納されます。
result = 0: タイムアウト時間内に指定した文字列を受信できなかった(タイムアウト発生)result > 0: 指定した文字列を受信した(左から何番目の引数に一致したかを示すインデックス番号が入る)
タイムアウトを設定し、result = 0 の場合にエラー処理へ分岐させることで、指定文字列を受信できない場合にマクロが無期限に待機(ハングアップ)することを防げます。
ただし、タイムアウトはあくまで待機時間の上限を設けるものであり、コマンド自体の成否を判定するものではありません。result > 0 は「指定した文字列を受信した」ことしか示さないため、コマンド自体の成功や失敗を判定したい場合は、前述のように終了コードをチェックする判定用文字列を出力させたり、実行結果を表す固有のメッセージを待つように設計してください。
まとめ:pauseとwaitを適切に使い分けて安定した自動化を実現する
今回は、Tera Termマクロにおける pause と wait の違い、および安全なスクリプト構築のための実践的な書き方を解説しました。
記事のポイントをまとめます。
pause(ミリ秒はmpause)は時間を基準にした休止であり、サーバーの応答状態を考慮しないため、キー入力間隔の調整など補助的な利用にとどめる。wait(またはwaitln/waitregex)はホストから受信した文字列を基準にした待機であり、動的な処理の流れを正確に制御するために使用する。- 待機を行う際は、
timeout/mtimeout変数 とif result = 0によるエラー分岐 をセットで記述し、無期限の待機(ハングアップ)を防ぐ。 - 「指定文字列の受信」と「コマンド実行の成功」は別物であることを理解し、成否判定が必要な場合は終了コードの確認などを組み合わせる。
これらのポイントを押さえることで、環境の変化に強く、エラーやハングアップに強い信頼性の高い自動化スクリプトを作成できるようになります。日々の運用業務の効率化にぜひ役立ててください。
以上で本記事の解説を終わります。
よいITライフを!
人気記事
- 1
- 2
- 3
- 4
- 5
思考の整理というテーマを、実務ですぐに使える具体的な「技術」として落とし込んだ一冊です。