WSHスクリプトの実行時に指定されたパラメータは、左から出現順にWshArgumentsコレクションに格納されるとともに、名前付きパラメータと名前なしパラメータにフィルタリングされ、前者はWshNamedコレクションに、後者はWshUnnamedコレクションにそれぞれ格納される。
名前付きパラメータは、スラッシュ(/)で始まり、変数の種別を示す「名前」、コロン(:)、「値」が表記されたものだ。例えば次のようなものである。
また、“:”や値の存在しない“/A”だけのようなパラメータも名前付きパラメータである。この場合は名前が“A”となり、値は空の文字列となる。
これに対し「test1」など、「/」以外の文字から始まるパラメータは「名前なしパラメータ」となる。UNIXコマンドや、UNIXを起源とするコマンドでは、パラメータ指定にハイフン(-)を使うものが多い。しかしWSHにおける名前付きパラメータの開始記号はスラッシュ以外の文字には変更できない。どうしてもハイフンを「-」を使いたい場合は、いったん名前なしパラメータとして(WshArgumentsコレクションで)ハイフン付きの文字列を取得し、最初の文字が「-」かどうかの判定をスクリプト内部で行うことになるだろう。
例えば、冒頭の例で使用した次のようなパラメータを指定すると、WScriptオブジェクトの状態は図のようになる。
cscript namedarguments.vbs test1 /A /Server:Server01 test2
WshNamedもWshUnnamedもコレクション・クラスなので、WshArgumentsコレクションと同様にスクリプトから扱うことができる。ただし図からも分かるとおり、WshNamedのItemプロパティは、エレメントを示す引数に番号ではなく、パラメータの名前を指定する。先ほどの「/Server:Server01」なら、WScript.Arguments.Named.Item("Server") と書くことで“Server01”が取得できる。
一方のWshUnnamedは、WshArgumentsと同じように0から始まる番号でパラメータを指定する。
例えば次のようにする。
WScript.Echo WScript.Arguments.Unnamed(0)
WScript.Echo WScript.Arguments.Named("Server")
実行結果は次のようになる。
C:\>cscript arg.vbs /Server:Server01 test1
test1
Server01
特定の名前付きパラメータが存在しているか(指定されたか)どうかを知りたければ、WshNamedのExistsメソッドで確認できる。
If WScript.Arguments.Named.Exists("A") Then
WScript.Echo "/A パラメータが指定されました。"
End If
実行結果は次のとおり。
C:\>cscript arg.vbs /A
/A パラメータが指定されました。
WshNamedでは名前と値が解釈されて格納されるものの、WshNamedにせよWshUnnamedにせよ、格納されるパラメータ自体はWshArgumentsのそれと変わらない。ただし前出の図からも分かるとおり、エレメントにアクセスするための番号(値)は、コレクションによって異なるので注意が必要である。
名前付きパラメータと名前なしパラメータはどのように使い分ければよいのだろうか。例えばいま、リモートから相手のコンピュータに接続して、何らかの処理を行うスクリプトを作ることになったとしよう。当然ながら、接続先のホスト・コンピュータはパラメータで指定する。またこれ以外のパラメータとして、タイムアウト時間とリトライ回数を指定するとしよう。
この場合、名前なしパラメータを利用するなら次のようになるだろう。
1: If WScript.Arguments.Count = 3 Then
2: strTarget = WScript.Arguments.Item(0)
3: nTimeOut = WScript.Arguments.Item(1)
4: nRetry = WScript.Arguments.Item(2)
5: Else
6: WScript.Echo "ターゲット名、タイムアウト時間、リトライ回数を" _
7: & "指定してください。"
8: WScript.Quit
9: End If
10:
11: WScript.Echo "ターゲットは " & strTarget
12: WScript.Echo "タイムアウト時間は " & nTimeOut
13: WScript.Echo "リトライ回数は " & nRetry
このスクリプトでは、単に指定されたパラメータを順にターゲット・ホスト名(strTarget)、タイムアウト時間(nTimeOut)、リトライ回数(nRetry)を示す変数に代入し、WScript.Echoメソッドで表示している。実行すると次のようになる。
C:\>cscript arg1.vbs Server01 30 5
ターゲットは Server01
タイムアウト時間は 30
リトライ回数は 5
スクリプトとしてはこれでまったく問題はない。しかしこのスクリプトを実行するユーザーは、パラメータの指定順序を覚えておき、順番どおりに正確に指定しなければならない。順番を間違えると、誤ったパラメータ値がスクリプトで処理されてしまう。
このような場合に名前付きパラメータを利用すると、ユーザーはパラメータの順番に頭を悩ますことなく、自由な順序でパラメータを指定できるようになる。
1: strTarget = WScript.Arguments.Named.Item("Target")
2: nTimeOut = WScript.Arguments. Named.Item("TimeOut")
3: nRetry = WScript.Arguments. Named.Item("Retry")
4: If strTarget = "" or nTimeOut = "" or nRetry = "" Then
5: WScript.Echo "ターゲット名、タイムアウト時間、リトライ回数を" _
6: & "指定してください。"
7: WScript.Quit
8: End If
9:
10: WScript.Echo "ターゲットは " & strTarget
11: WScript.Echo "タイムアウト時間は " & nTimeOut
12: WScript.Echo "リトライ回数は " & nRetry
実行結果は次のとおり。
C:\>cscript arg1.vbs /Target:Server01 /Retry:5 /TimeOut:30
ターゲットは Server01
タイムアウト時間は 30
リトライ回数は 5
C:\>cscript arg1.vbs /TimeOut:30 /Retry:5 /Target:Server01
ターゲットは Server01
タイムアウト時間は 30
リトライ回数は 5
スクリプトの1行目から3行目にあるとおり、WshNamedコレクションの名前付きパラメータは、パラメータの「名前」を指定してアクセスできる。従ってパラメータの指定順とは無関係に、正しいパラメータを対応する変数に代入できる。この実行例では、1回目と2回目でパラメータの並び順を変えて指定しているが、結果は同じになっている。
名前付きパラメータを利用することで、パラメータの意味を明確にできることがお分かりいただけると思う。この例では、あらかじめWshNamedのExistsメソッドにより必要なパラメータ数を調べるのではなく、パラメータを取得した変数に値が入っていなければエラー・メッセージを表示して終了するようにした(4行目〜8行目)。値が指定されていなかった場合にはデフォルトの値をスクリプト側で与え、処理を続行するようにすれば、パラメータを省略可能になる。
名前なしパラメータはパラメータの「名前」を指定しなくてよいので簡便だが、異なる複数のパラメータを指定するのには向かない。1つないし2つ程度の少数のパラメータしかない場合や、同一タイプのパラメータだけを複数指定する場合(例えば順番によらず複数のホスト名を指定するなど)ならよいが、種類の異なる複数のパラメータを指定する必要がある場合には、名前付きパラメータを利用すべきだろう。
Copyright© Digital Advantage Corp. All Rights Reserved.