【実務・中級編】【対話型シェルの入力割り込み処理】WScript.StdIn.AtEndOfLineとSleepを組み合わせたノンブロッキング入力監視 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptで実現する「ノンブロッキングCLI」:バックグラウンド処理と入力監視の極意

業務自動化の現場において、VBScript(WSH)は「枯れた技術」と揶揄されることがある。だが、真のエンジニアは知っている。OSの深層に最も近く、極めて軽量に動作するこの言語こそ、真の「グルーコード(接着剤)」であることを。

多くの開発者が躓くのが、「処理を実行しながら、ユーザーの入力(割り込み)を拾う」という命題だ。通常、`WScript.StdIn.ReadLine` を実行すればスクリプトは止まる。しかし、我々は止まってはならない。

今日は、CScript環境下で、バックグラウンドの重いタスクを回しながら、ユーザーのキー入力をリアルタイムに監視する「ノンブロッキングI/O」の設計手法を伝授する。

なぜ従来の「同期処理」ではダメなのか?

一般的なツール作成者は、入力を待つ際に `ReadLine` を使う。これは「ブロッキング処理」であり、入力があるまでスクリプトの実行スレッドが完全に停止する。

もしあなたが、ログの監視やAPIへの定期ポーリングをしながら、特定のキー入力(例えば「Q」で停止など)を待つツールを作りたい場合、同期処理ではそれが物理的に不可能だ。この壁を突破するには、「ポーリング監視」という戦略が必要になる。

設計思想:Non-Blocking I/O パターン

今回の肝は `WScript.StdIn.AtEndOfLine` を活用することだ。
これは「現在、入力ストリームに未読のデータがあるか」を判定するプロパティである。これと `WScript.Sleep` を組み合わせることで、「CPU負荷を抑えつつ、入力を監視し続ける」という理想的なループ構造を作る。

実装コード:堅牢なノンブロッキング・シェル

このコードは、メインループでバックグラウンド処理を回しつつ、ユーザー入力を非同期にチェックするテンプレートだ。プロダクション環境での安定性を考慮し、エラーハンドリングを最小限に組み込んでいる。

‘ CScript.exe で実行すること (wscript.exeではStdInが使えないため)
Option Explicit

Dim bRunning : bRunning = True
Dim iCounter : iCounter = 0

WScript.StdOut.WriteLine “— 監視システム開始 [Q]キーで終了 —”

Do While bRunning
‘ 1. 入力ストリームの監視
‘ AtEndOfLineは入力がバッファにあるかを確認する
If Not WScript.StdIn.AtEndOfStream Then
‘ ReadLineで1行分読み取る
Dim sInput : sInput = LCase(WScript.StdIn.ReadLine)

If sInput = “q” Then
WScript.StdOut.WriteLine “終了シグナルを受信しました。”
bRunning = False
Else
WScript.StdOut.WriteLine “コマンド ‘” & sInput & “‘ を受信”
End If
End If

‘ 2. メインのバックグラウンド処理
‘ ここでDB接続やファイル監視などの重い処理を回す
iCounter = iCounter + 1
If iCounter Mod 100 = 0 Then
WScript.StdOut.WriteLine “バックグラウンド処理中… (ループ回数: ” & iCounter & “)”
End If

‘ 3. CPU負荷を抑えるためのSleep (超重要)
‘ 0にするとCPUを100%消費するため、最低100ms程度は空けるのが定石
WScript.Sleep 100
Loop

WScript.StdOut.WriteLine “システムを停止しました。”

現場で生き残るための「4つの鉄則」

コードをコピペするだけでは、現場の荒波は越えられない。この実装をプロダクションレベルにするための知見を共有する。

1. CScript.exe を強制する

WScript.exe(GUI版)で実行すると `StdIn` が存在せずエラーになる。バッチファイル内で以下のように記述し、強制的にCScriptへ切り替えるのが「プロの作法」だ。

@echo off
cscript //nologo “%~dp0your_script.vbs”

2. Sleep の重みを知る

`WScript.Sleep` の値は、ツールの「応答性」と「負荷」のトレードオフだ。

  • `Sleep 10`: 応答性は最高だが、CPU負荷が高まる。
  • `Sleep 1000`: 負荷は低いが、入力に対するレスポンスが鈍い。

現場では、バックグラウンド処理の重さに合わせ、100ms〜500msの間で調整するのが最もバランスが良い。

3. ファイル・DB連携時の注意点

このループ内でファイルI/OやDB接続を行う場合、「ループのたびに接続/切断」を繰り返すのは愚策だ。接続オブジェクト(ADODB.Connection等)はループの外でインスタンス化し、ループ内ではデータの読み書きのみを行うこと。さもなくば、接続リソースの枯渇(コネクションリーク)でツールは数時間で死ぬ。

4. 異常終了対策

バックグラウンド処理が複雑になる場合、`On Error Resume Next` で囲むのは最低限だが、さらに `Err.Number` をログ出力する仕組みを導入せよ。スクリプトが黙って消えるのが、運用において最も恐ろしい事態である。

最後に:なぜ今、VBScriptなのか

モダンな言語(PythonやGo)がある中で、なぜ我々がVBScriptを語るのか。それは、「クライアントPCの環境を一切汚さず、メモ帳一つで即座に運用を開始できる」という圧倒的なスピード感こそが、業務改善の現場で最も求められる価値だからだ。

この「ノンブロッキング・シェル」のテンプレートを武器に、あなたの手元にある退屈なルーチンワークを、洗練された自動化プロセスへと昇華させてほしい。

健闘を祈る。

タイトルとURLをコピーしました