Let's大谷家 あんたの日記

Just another WordPress site

Windowsバッチ「FOR」の使い方(覚書)

      2014/10/18

先日、APサーバーのサービス再起動を行うバッチを作ることになり、チョロチョロとサンプル探して作成したんだけど、似非プログラマーなので難しい説明で唸ってしまった…
とりあえず、理解はしたみたい(?)なので覚書を作成。

○やりたかったこと
・現在サービスが起動してるか確認
・起動してれば再起動
・起動してなければ起動

Windowsバッチの「FOR」コマンドを使えば良いらしい。
「FOR」と聞くと、単に繰り返し処理だと思うが、オプションで以外にいろいろ出来るそうだ。
サンプルコードは以下のとおり。



---------------------------------
set SERVICE=[サービス名]
set LOG=[ログファイル名]
FOR /f "tokens=1,2,3,4 USEBACKQ DELIMS=	 " %%A IN (`sc query "%SERVICE%" ^| findstr -i state`) DO (
 if "%%D"=="RUNNING" echo %date% %time% INFO サービス停止 >> %LOG%
 if "%%D"=="RUNNING" net stop "%SERVICE%" 2>> %LOG%
 if "%%D"=="RUNNING" GOTO ENDIF
 if "%%D"=="STOPPED" echo =%date% %time% WARNING サービス起動中 >> %LOG%
)
:ENDIF
net start %SERVICE% 2>> %LOG%
---------------------------------

「/f」オプションがキモ。
標準出力された文字列の1行を「解析文字列」にて切り出すことが可能。
オプションの内容を、左から順に説明する。

・/f(オプション指定)
 ファイル解析による繰り返しを実施

・”tokens=1,2,3,4 USEBACKQ”(解析文字列)
 解析文字列を記述する箇所。
 いろんなものが指定できるが、ここでは今回利用するものと覚書の追加分だけを記載。
 [tokens]
  「区切り文字」で区切った文字の取得する番号を指定
  上記は、左から1~4つ目までを全て抽出
  ”tokens=1,4″とすると、1つ目と4つ目のみ抽出
  ここで指定した抽出データは、この後出てくる「変数」に格納
 [USEBACKQ]
  この後出てくる「コマンド」の文字列の囲みを「(`)バッククォート」にする
  この指定がない場合「(”)ダブルクォート」で囲むことになるが、コマンド内で「(”)ダブルクォート」を利用することが多いため、指定して「(`)バッククォート」にしておいたほうが良い(好みはあるが・・・)
 [DELIMS]
  特殊な区切り文字がある場合に指定
  デフォルトでは「タブ」「スペース」を判断
  それ以外を指定する場合に設定
  ちなみに、複数設定することも可能
  複数設定で空白をデミリタに含めたい場合は、最後に設定すること(例[,+タブ+空白の場合]:”DELIMS= , “)

・%%A
 標準出力を /fの「解析文字列」で分解した値を設定する変数の開始文字を設定
 「A」を指定した場合、tokensで複数の区切り文字を指定した場合、A:tokensの1つ目に指定した値、B:tokensの2つ目に指定した値と、指定変数文字列の次の文字を変数名として勝手に設定
 なお、”%”を2通続けるのは、バッチ内では必須
 バッチ内で”%”と記述すると環境変数と判断されてしまうため、バッチ内変数として利用するため同一文字でエスケープ

・IN (`sc query “%SERVICE%” ^| findstr -i state`)
 ()内の処理対象とする
 処理対象は、カレントのファイル名でもよし、文字列でもよし、コマンドでもよい
 以下、例として処理対象に設定した内容でどのように処理されるかを記載
 
 1)IN (A B C)
  文字列”A B C”と判断
  /fで指定[tokens]を設定すると、”A”,”B”,”C”の文字が各変数に設定
 2)IN (*.txt)
  コマンド実行したかれんどディレクトリ内の拡張子”txt”のファイル内を1行ずつ取得して繰り返し処理
 3)IN (`sc query “%SERVICE%” ^| findstr -i state`)
  scコマンドの標準出力を1行ずつ「解析文字列」で分解して繰り返し処理
  なお、”|”の右にある”^(キャレット)”は、FORコマンド内に記載するため、FORの演算子として識別されないようにエスケープするためにつける。

  ※補足(scコマンド)
   上記のscコマンドは、指定したサービスの[state]の情報だけを標準出力する指示を出している。
   [findstr]が指定文字列を含む行だけを取得するコマンド
   unix系のgrepと同じ(grepについて書き始めると1つの記事になってしまうので、個々では省略www)
   [-i]は文字の大小文字を判断しない[findstr]のオプション

・DO()
 繰り返し処理を行うコマンドを記載

上記を実行した時、どんな動きになるかを記載。

・scコマンドの結果(標準出力の内容)
 ” STATE : 1 STOPPED”
 単体で実行すると、こんな感じの結果が標準出力で表示される。

・変数の設定値
 以下のように設定される。
 
 %A⇒STATE
 %B⇒:
 %C⇒1
 %D⇒STOPPED

・DO内の処理
 if “%%D”==”RUNNING”
 ⇒%Dが「STOPPED」なので、その文字が”RUNNING”の場合に処理させる。

かなり汎用的に利用出来るコマンドなので、そのシュチュエーションにより、いろいろな書き方が出来そうなので、サンプル作り始めたらキリがない。
なので、ズバッと自分の出来る事が記載されている情報は皆無なんでしょうね。
ちゃんとしたPGなら汎用的な内容を見れば理解出来るのでしょうが、自分はダメだw
PG失格!w

今更、Windowsバッチの記事ってのもなんだかなーな感じでしたが、とりあえず覚書でした。

 - バッチ, プログラミング

ad

ad

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

  関連記事