2005年12月04日

cmd.exe と、遅延展開

今まで、コマンドプロンプトと一貫して呼んできましたが、Win98 までは確か 「MS-DOS プロンプト」 って言われていました。そして、Win2000 から 「コマンドプロンプト」 って呼ばれるようになりました。一体何が変わったのでしょう?

って、さも知ったように書いてますが、詳細までは解かりません (^^; が、その実体が command.com から cmd.exe に変わり、機能が追加されたことは解かります。

メニューの 「コマンドプロンプト」 を右クリックしてプロパティを表示すれば、何が起動されているか調べられますよ。 cmd.exe だと思いますが・・・

/? でヘルプを表示したとき、拡張機能がどうの・・・って、よく出てきますよね。これも追加された部分です。デフォルトではこの拡張機能は ON なので、cmd.exe では使用して問題ありません。これに関しては既に色々使ってきました。for コマンド/f オプション などがそうでしたよね。

でも、デフォルトで OFF の機能だけど、使い方によっては便利なものがあります。っていうより、多少プログラムを書く人にとっては変数の展開のタイミングに違和感のあったと思います。if 文の括弧の中や、for 文のループの最中では、変数を変更出来なかったのですから・・・。

この点を解決するのが 「遅延展開」 と言われるもので、通常、コマンド実行前に1度だけしか評価されていなかった変数が、参照のタイミングで評価させることが出来るようになります。if 文の括弧の中や、for 文のループの最中でも代入した値が反映されることになり、イメージ通りの処理が可能になります。

遅延展開」 を使わなくても ラベルgoto 文でループさせれば反映可能なんですが、見通しが悪くなるんですよね・・・。C言語では goto 文があるんですが、使うな! って言われているくらいです。

まぁ、折角ある物ですから、有効にする方法を考えましょう。

その1: レジストリの設定を変更し、常時遅延展開有効で起動させるようにする。・・・ん〜、これは止めておきましょうね (^^;

その2: コマンドラインで cmd.exe または cmd コマンド/v:on を指定して起動する。cmd コマンドの詳細は、例によって cmd /? ですよ。

あっ、気付きました? cmd.execmd コマンド って同じですよね。新たに遅延展開を有効にしてコマンドプロンプトを起動しているんですね。だから、例えばバッチファイルで次のように書いてもうまくいかないんですね。

cmd /v:on
set test=
for /l %%i in (1,1,5) do (set test=!test!%%i)
echo %test%


この場合、cmd /v:on で新たに起動されたプロセスが終了しないと、次の行が実行されません。つまり、遅延展開を有効にしたプロセスでは実行できないんです。

そんじゃー意味ね−じゃん!

そうそう、だから一工夫するんですよ。遅延展開を有効にしたプロセスで実行すればいいのですから、別ファイルに書いて /c オプションを使用しましょう。

その方法でテストしてみた状況が この画面 です。delay_main.bat からは cmd /v:on を使って delay_test.bat を実行しています。delay_call.bat では、call コマンド で普通に delay_test.bat を呼び出しています。違いが判りますよね。cmd /v:on を使用したほうは、見事に ケンシロウ になっています。

まぁ、コレだけ説明しておいて何ですが、必ず使えってことじゃ無いですし、必要ない場合も多いですよね。知らずに使えないんじゃなくって、知ってて使わない。このブログでは、そんな方向で進めていきます。

あっ、でも便利ですから、皆さんは使ってみてくださいね。

コラ〜!ドッチなんだ〜〜!!


注意: 画面のコードを書いて試す場合、echo Start ・・・ の行は注意して下さいね。echo を書き忘れると Start がコマンドとして認識されます。Start の後に自分自身のファイル名が書いてあると・・・

自分自身を無限に呼出し続ける無限再帰呼出しの完成です。スタックを使い尽くすまで止まりません(たぶん)。壊れることは無いと思いますが。

怖いもの見たさ?

まぁ、それもありかもね・・・



応援ポチ  お願いしま〜す。

posted by Woody at 00:43 | 静岡 晴れ | Comment(0) | TrackBack(0) | コマンドプロンプト
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

この記事へのTrackBack URL
http://blog.seesaa.jp/tb/10161005
※特に許可した場合を除き、一方的な TrackBack は
  SPAM として削除いたします。ご了承ください。