- 北の空からみなみへ -
exblog staff

<   2018年 03月 ( 7 )   > この月の画像一覧
1 line FizzBuzz benchmark
2018年 03月 19日

1行FizzBuzzの千回ループベンチを、仕事終わりの帰りがけに最遅のマシンにもう一度走らせてみた。
すると、(うっかり表示を垂れ流したとはいえ)140msという遅さを叩き出した。
そういえば、Celeronのこのマシンと、core i3の2台には、Microsoft Office がインストール済みだった。
いかにも疑わしい。これは再確認しておきたい。

それとともに、マシンの違いによる速度差と、コードの中身でのそれとを比較したくて、最初コード最後のものとでベンチをやり直してみました。
まさかofficeをアンインストールするわけにもいかず、前回ベンチを取った時と同じく再起動しての実行です。

やっている途中で速度がばらつき、出力をnulにしないで表示をさせてみると、たまにひっかかっている感じになりました。
あれ?これって、もしかしたらバックグラウンドプロセスの影響かな?
そこでネットから切り離して、Defenderのリアルタイム監視をを停止したら、速度は上がりました。

そういえば、業務側は最小限のウイルス対策で済むよう物理的に外部と切り離し、セキュアに保っていたのでした。(アンチウイルスソフトは入っているが、当初稼働のtm社はオーバーヘッド大きすぎて、より軽いm社のものだし、いまではサポート切れでサーバのウイルスデータベースの更新も停止)
そういう意味では、前回取得していたのはマシン性能よりもバックグラウンド負荷のベンチマークだった。こう言えるかも知れない。

んでやってみたけっかはっぴょう。旧コード(文字変数逐次書き換え版)の出力on と off、最終コード(計算分岐最小限のリスト展開版)で 出力off と on です。
c0062295_20245588.gif

ふむふむ。表示のON/OFFでは、8~9ms程度の差。数文字x百行程度の文字出力では、負荷のほうはそれほどではない。
けれども、コード差では3倍の速度差。。
やはり除算(剰余)はプログラムの速度低下の要素なのですね。
(IF文もそうらしいが、このコードでその差は大きくない。むしろ変数の部分書き換え多用が元凶か。)

あとでまたやり直したくなった時に、効率的にできるように手順をメモ


最初に、CMD/v:on でコマンドプロンプトを起動(具体的には次のコマンド入力)
color f0&cmd/v:on/k"prompt $g &title Celeron G1620 2.7GHz"

回数をセット
set $count=1000

次に新旧FizzBuzzのコード引数を、変数FizzBuzzとして代入

こちら新の方
set FizzBuzz="for /L %a in (0,1,6) do for %A in (1 2 Fi 4 Bu Fi 7 8 Fi Bu 11 Fi 13 14 FizzBu) do if %a11==6%A (exit) else if %A gtr a (echo.%Azz) else set/a $=15*%a+%A&echo."
こちら旧のほう
set FizzBuzz="for /L %A in (1,1,100) do (set/a I=%A%3,Z=%A%5>nul&(for %B in (!I!) do set I=!I:~%B,1!)&for %B in (!Z!) do set Z=!Z:~%B,1!)&set $= &(if defined I set $=!$!Fizz)&(if defined Z set $=!$!Buzz)&set $=!$:~1!&(if not defined $ set $=%A)&echo !$!"

ベンチマークを実行 (%FizzBuzz% 直後の閉じカッコ直後に >nul を出し入れて表示を on/off)
(for /L %z in (1,1,!$count!) do cmd/q/v:on/c%FizzBuzz%)>nul&set etime=!time!&set/p<nul=%time%-!etime!/!$count!Loop Average = &set/a ltime=((1000*(3600*!etime:~0,2!+60*(1!etime:~3,2!-100)+1!etime:~6,2!-100)+1!etime:~-2!0-1000-(1000*(3600*%time:~0,2%+60*(1%time:~3,2%-100)+1%time:~6,2%-100)+1%time:~-2%0-1000))+86400000)%86400000/!$count!&echo ms


more
[PR]
by bucmacoto | 2018-03-19 02:49 | quote/data | Trackback | Comments(0)
コマンドプロンプトの1行ベンチマーク
2018年 03月 11日
先の1行FizzBuzzを反復実行して、所要時間から処理速度を判別しようとしたら、老化脳では「どのくらい?」という程度感覚が掴めなかった。
(また、処理出力をNULリダイレクトで隠してしまえばいいが、表示させてしまうと、100行×1000試行=10万行の彼方に開始時刻が流れ去っていて確認に困った)

なので、一行FizzBuzzの反復試行ルーチンのさらに前後に手を入れて、開始時間を表示し→計算反復の実行→終了時間を表示し所要時間を表示する。ように書き加えてみた。
(例によって後で再度使い回す場合のために、備忘録として記録)

説明文を簡便化するために、実行する本体を仮に FIZZBUZZとおこう(代入だね)。

実行土台となる CMD.EXE は、スイッチ /v:on で遅延変数展開ONでコマンドプロンプトを起動しておく。
(現在時刻変数 time の一行内の時間差から、所要時間を算出するのだから、これは必須。)
このところ、砂場遊びでは次の一行をコマンドプロンプト起動直後に入れるのがルーチン化している。(自動でこうなるようにできるが、それは禁じ手=職場PCなので)

color F0&cmd/v:on/k prompt $g ^&title SandBox

FIZZBUZZの1,000回実行コードはこんな感じ。

for /L %z in (1,1,1000) do FIZZBUZZ
これを画面に表示させずNULへ流すには、括弧で括ってリダイレクトアウト。
(for /L %z in (1,1,1000) do FIZZBUZZ)>nul

この前に現在時刻を取得し、深夜0時からのミリ秒数計算のコードをおく。(バッチ内でない限り、set/a で代入するための計算結果はコンソール表示されてしまうので、まとまるように書く)

バッチ出力を最低限の改行で済ませるために、コードは set/p&nul="改行なし表示出力" の形式を多用。
投稿ボックス内で自動改行されると空白などが分かりにくいから横長表示で。
(ついでにマウスオン解説表示も多用)
この上には表示や計算結果や解説が表示されます。
set/p&nul=start=%tilme%[
start= 01:23:45.67[5025670]
set/p&nul=start=%tilme%[
&set stime=%time%
変数 stime(=start time) に時刻を代入(※実のところ1行処理なら無用=後で解説)
set stime=%time%
&set/a start
変数 start にミリ秒変換した開始時刻を代入(表示もされる)
set/a start
=1000*(!stime:~0,2!*3600+(1!stime:~3;2!-100)60+(1!stime:~6,2!-100)
start= 01:23:45.67[5025670] "時刻文字列"を秒数に
!stime:~0,2!*3600+(1!stime:~3;2!-100)60+(1!stime:~6,2!-100)
)+1!stime:~-2!0-1000
start= 01:23:45.67[5025670]
+1!stime:~-2!0-1000
&echo.]
start= 01:23:45.67[5025670]
echo.]
&

後半もほとんど同じコードですね。
この上には表示や計算結果や解説が表示されます。
&set etime=!time!
変数 etime(=end time) に時刻を代入完了「直後」の時刻
set etime=!time!
&set/p&nul=end=!etime![
start= 02:08:45.67[7725670] average=270ms
set/p&nul=end=!etime![
&set/a end
変数 end にミリ秒変換した処理完了時刻を代入(表示もされる)
set/a end
=1000*(!etime:~0,2!*3600+(1!etime:~3;2!-100)60+(1!etime:~6,2!-100)
end= 02:08:45.67[[7725670] average=270ms "時刻文字列"を秒数に
!etime:~0,2!*3600+(1!etime:~3;2!-100)60+(1!etime:~6,2!-100)
)+1!etime:~-2!0-1000
end= 02:08:45.67[7725670] average=270ms
+1!etime:~-2!0-1000
&set/p&nul=] average=
end= 02:08:45.67[7725670] average=270ms
set/p&nul=] average=
&anp;set/a ltime=(!end!-!start!)/1000
end= 02:08:45.67[7725670] average=270ms(計算結果は改行なしで表示される)
set/a ltime=(!end!-!start!)/1000
&echo.ms
end= 02:08:45.67[7725670] average=270ms
echo.ms

あとは、前半コード+FIZZBUZZコード+後半コード のサンドイッチで出来上がり。
ということで職場で私が触れる範囲のPCやWSでベンチマークを実行してみました。(結果はmore欄で)

ですが、この投稿にまとめていて気づいたのです。
遅延変数展開下の環境では、変数参照に !変数!(遅延展開=実行時に動的変数として展開)と %変数%(時即時展開=コマンドライン改行の瞬間に一行内の変数は確定)とが、「どちらも」使えるのでした。

つまり、サンドイッチに挟まなくても、
(処理) & (終了時刻「!time!」・開始時刻「%time%」で所要計算)
みたいにすれば、より簡明な記述ができたのですね。。。。orz...

さらにループ回数を柔軟に設定できるように書き換えると、こうなります。
(実地検証でこけまして修正)
(if not defined $count set/a $count=1000)&(for /L %z in (1,1,!$count!) do FIZZBUZZ)>nul&set etime=!time!&set/p<nul=%time%-!etime!/!$count!Loop Average = &set/a ltime=(1000*(3600*!etime:~0,2!+60*(1!etime:~3,2!-100)+1!etime:~6,2!-100)+1!etime:~-2!0-1000-(1000*(3600*%time:~0,2%+60*(1%time:~3,2%-100)+1%time:~6,2%-100)+1%time:~-2%0-1000))/!$count!&echo ms
1日を跨ぐ場合には、ltime が負数になるので、86400000を加え86400000で剰余を取るなどして正数化したミリ秒数を 試行回数 $countで割る。このように扱う必要もあるけど、そこまで使うケースはおそらくない。
(if not defined $count set/a $count=1000)&(for /L %z in (1,1,!$count!) do cmd/q/v:on/c"for /L %a in (0,1,6) do for %A in (1 2 Fi 4 Bu Fi 7 8 Fi Bu 11 Fi 13 14 FizzBu) do if %a11==6%A (exit) else if %A gtr a (echo.%Azz) else set/a $=15*%a+%A&echo.")&set etime=!time!&set/p<nul=%time%-!etime!/!$count!Loop Average = &set/a ltime=((1000*(3600*!etime:~0,2!+60*(1!etime:~3,2!-100)+1!etime:~6,2!-100)+1!etime:~-2!0-1000-(1000*(3600*%time:~0,2%+60*(1%time:~3,2%-100)+1%time:~6,2%-100)+1%time:~-2%0-1000))+86400000)%86400000/!$count!&echo ms


じっこうけっか と 小さな説
[PR]
by bucmacoto | 2018-03-11 22:09 | &Tips;&code; | Trackback | Comments(1)
砂場遊び(1行FizzBuzz)/後片付け
2018年 03月 08日
砂場遊び(1行FizzBuzz)

bugmacotoとも言うべきお間抜けコードを前投稿(more欄)で晒した。Windows実機でちゃんと動くコードに直したので再掲する。
なお、ちょこっとずつ解説入れておこう。(自分でも後から可読する自信はないらしい)

まずは、最短(なんちゃってなので105までカウントアップが突っ走り)なBizzBuzz方言版

cmd/q/v:on/c "for /L %a in (0,1,6) do for %A in (1 2 i 4 u i 7 8 i u B i D E izzBu) do if %A gtr f (echo.B%Azz) else set/a $=15*%a+0x%A&echo."
142 ↑ byte
    cmdのオプション
  • /q : echo off状態で起動
  • /v:on : 変数の遅延展開を有効にした状態で起動
    バッチで SETLOCAL ENABLEEXTENSIONS 宣言下と同じ状態
  • /c : 残り全部を引用符で囲まれたパラメータ(引数)を続けると、最初と最後の引用符が外されてコマンドライン上で実行される感じになる。
    (マイクロソフトのcmd.exeの文字列を扱う実装は、ちょっとずつ状況に応じて変化する=一貫性はない感じ。
     BASIC時代から、対称性の破れみたいな実装を好んでいる感じがする。)
    遅延展開有効下での例 : 比較文字として キャレットで「|」と引用符「"」を比較
    引用符にキャレットって無効では?(なんと有効でした。むしろ \" なんて書くとエラーします)

    > if ^| gtr ^" echo !time: =0!
    20:00:00.00

    > if ^| gtr ^" echo.!time: =0!
    !time: =0!

    echoの後ろに、空白区切りとピリオド区切りとで、変数の拡張展開されたり、されずにそのまま文字列表示になったり。

次に16進アイデアを温存したままで、方言ではないFizzBuzzへの対応版
無理やりな文字列比較をして動くようになったバージョン
なお、16進コードの A~F は大文字でも小文字でもいいらしい。
さらには、引用符あっても(0x"F" と書くとそれは 15 になる)OKという実装。

cmd/q/v:on/c "for /L %a in (0,1,6) do for %A in (1 2 Fi 4 Bu Fi 7 8 Fi Bu "b" Fi "d" "e" FizzBu) do if %A gtr "f" (echo.%Azz) else set/a $=15*%a+0x%A&echo."
156 ↑ byte
    if での比較は、記号 < 数字 < 文字
    (同じ文字なら大文字が大きいが、大文字の A は小文字の b より小さいという定義 )
  • 例 :
    >if b gtr A echo
    ECHO は <ON> です。
  • set/a での変数へ代入する計算結果はバッチ内では結果は表示されないが、コマンドライン上では表示される。
    なお、改行はされない。
    (echo ではなく set/p<nul= で出力したのと同様な吐き出し方をしてる)
  • set/a $= : $は仮変数(ダミー)
    昨日の寝ぼけた式は間違いで、こちらがちゃんとしたカウントアップ。
  • &echo. : 数値は吐き出されても改行はされていない。なので空改行を入れている
    (echo だけでは 「ECHO は <ON> です。」が出るのはおなじみ)

文字比較式があんまりなので、16進数のアイデアを放棄したらむしろ短くなった。
これでかなりすっきりして、分かりやすくなった。

cmd/q/v:on/c "for /L %a in (0,1,6) do for %A in (1 2 Fi 4 Bu Fi 7 8 Fi Bu 11 Fi 13 14 FizzBu) do if %A gtr a (echo.%Azz) else set/a $=15*%a+%A&echo."
149 ↑ byte
  • >ここでは、gtr で 最小の英文字 a と文字比較している。
    より一般的にするなら、if %A geq a とすることで、変数%Aに代入された全ての文字(記号と数字以外)が処理対象となる。
    結果、else 以降は数字処理に専念となる。
  • %A=Fi : 後ろに zz で Fizz
  • %A=Bu : 後ろに zz で Buzz
  • %A=FizzBu : 後ろに zz で FizzBuzz

最後に仕上げ。

FizzBuzz問題は、1から100 という条件なので、それに対応する IF文を加える。
cmdの /c スイッチに続くのが引用符つきのパラメータの場合は、直後の空白を削っても正しく解釈されるのでそうした。

cmd/q/v:on/c"for /L %a in (0,1,6) do for %A in (1 2 Fi 4 Bu Fi 7 8 Fi Bu 11 Fi 13 14 FizzBu) do if %a11==6%A (exit) else if %A gtr a (echo.%Azz) else set/a $=15*%a+%A&echo."
173 ↑ byte
    遅延変数展開下とはいっても、%変数%の形式はしっかり有効なまま。
    (改行するまでは、展開=反映されない変数として普通の環境同様に扱われる)
  • if %a11==6%A (exit) ← これはOK
  • if %a%A==611 (exit) ← これNG
  • ※ なぜなら %a% という変数展開を優先されてしまうので 下の例では
    「%a%A」という4文字を 611 と比較する式に解釈される。
    そこで、たすき掛けにしてやるとまともに動いた。


(more欄のスクリーンショットは撤廃)→ 反復実行の前後時間から平均所要時間を算定の 1行ベンチマークテスト については次の投稿で。
[PR]
by bucmacoto | 2018-03-08 21:13 | &Tips;&code; | Trackback | Comments(0)
砂場遊び(1行FizzBuzz)
2018年 03月 08日
へっぽこ腕試しに、やってみた。(手元にwindowsマシンがないのでアイデアを練ること1日。コード作業に試行錯誤で数時間)
環境文字指定の自己参照、と、文字切り出し位置を変数で指定するのに for 文で変数を作ればできそうというアイデアで挑戦。
cmd/q/v:on/c "for /L %A in (1,1,100) do (set/a I=%A%3,Z=%A%5>nul&(for %B in (!I!) do set I=!I:~%B,1!)&for %B in (!Z!) do set Z=!Z:~%B,1!)&set $= &(if defined I set $=!$!Fizz)&(if defined Z set $=!$!Buzz)&set $=!$:~1!&(if not defined $ set $=%A)&echo !$!"
254 byte
実行結果
c0062295_19155944.gif

私にはこれが限界だったが、さすがはプロの方は更に100Byteほども小さく仕上げていた。(コードは他人様のですので実行結果だけ表示)
c0062295_19234540.gif

FizzBuzz問題についての、Wikipediaの解説

もう一日の熟考結果
[PR]
by bucmacoto | 2018-03-08 00:47 | &Tips;&code; | Trackback | Comments(0)
cmd.exe 砂場遊び /3.5~番外地後片付け
2018年 03月 07日
先の ワンライナー番外地 の投稿でキャレット使いまくりが恥ずかしいと書いた。

ふと文字列扱いのネタを思い出して引っ張り出してみた。
こちらは1月にXP上で変数の挙動テストした時のスクリーンショット。
c0062295_21053456.gif
なんだか分かりにくいが中ほど過ぎで、for /f "delims=" %c in (" 123 " 456 " 789 ") do echo %~c となっているところを見てほしい。引用符の最初と最後だけが外れるように見えている。

そういえば、cmd/exe へのパラメータ渡しは、引用符であればキャレット外せるのだと気付いた。

cmd/? でヘルプを読むと、次の部分の2番目に該当させればよさげである。
/C または /K が指定されている場合、スイッチの後の残りのコマンド ラインが
コマンド ラインとして処理されます。次のルールが引用符 (") の処理に使われます:
  1. 次のすべての条件に一致する場合、コマンド ラインの引用符が有効になり
    ます:

    - /S スイッチがない
    - 引用符が 1 組ある
    - 引用符の中に特殊文字がない
    (特殊文字は &<>()@^| です)
    - 引用符の中に 1 つ以上のスペースがある
    - 引用符の中の文字列が、実行可能ファイルの名前である

  2. 最初の文字が引用符であるにも関わらず上の条件に一致しない場合は、最初
    の引用符とコマンド ラインの最後の引用符が削除され、最後の引用符の後
    のテキストが有効になります。
そうして、以下のように修正した。(パス数も99を上限に)
cmd/q/v:on/k "prompt $g &for /L %i in (101,1,199) do set i=%i&for /F "delims=;" %p in ("!PATH!") do set $path!i:~1!=%p&set path=!PATH:%p;=!&if not defined PATH set $path&set/a i-=100>&2&exit !i!"
(この実行環境はWindows 7)
c0062295_15264611.gif


これで更に連結すると、パス文字分割ワンライナープログラムが一丁あがり
c0062295_15340265.gif

cmd/q/v:on/k "prompt $g &for /L %i in (101,1,199) do set i=%i&for /F "delims=;" %p in ("!PATH!") do set $path!i:~1!=%p&set path=!PATH:%p;=!&if not defined PATH set $path&set/a i-=100>&2&exit !i!">tmp.txt&(for /F "delims=" %A in (tmp.txt) do set %A)&del tmp.txt

で、やってみて気付いたのだが、ヘルプの中で、「最初と最後の引用符」みたいに書いてあったが、上記の場合にはちゃんとcmd.exe へ渡すパラメータの外で、連結されていた。(ちゃんと動いている)
引用符直後にリダイレクト記号があるからなのかわからないが、しばらく砂場遊びを離れてから後で見直すと、戸惑うかもしれない。

※追記※ 上記を 遅延環境変数展開(CMD.exe /v:on)下で実行してはなりません。(バッチ流用時には要注意です)
 理由 = !PATH! の文字が引用符内で展開されてコマンド(cmd/q/v:on/k)に渡されてしまいます。
(この現象確認は、Windows XP SP3 においてなされました)


xp上で動くchoice コマンドもどきは改善途上だが、少しだけ進化
[PR]
by bucmacoto | 2018-03-07 18:15 | &Tips;&code; | Trackback(1) | Comments(0)
砂場遊び /ワンライナー番外地
2018年 03月 04日
エラーレベル(%errorlevel%)をセットするのに cmd/c exit <数字> とやると、任意の数のエラーレベルを戻り値として返すことができると気づいた。

そこで、パス文字列を 擬似配列変数に分解し、エラーレベルとしてパス文字のフォルダ数を返し、パスの擬似配列リストを標準出力するワンライナーを書いてみた。
(windows 10 と XP で動作確認)

キャレットエスケープ使いまくりなのが恥ずかしい。
cmd/q/v:on/k prompt ^^^> ^&path=%path%;^&path=!path:;;=;!^&for /L %i in (1001,1,1999) do set/a $i=%i^>nul^&set $i=!$i:~1!^&for /F "delims=;" %p in ("!PATH!") do set $PATH!$i!=%p^&set path=!PATH:%p;=!^&if not defined PATH set/a $c=%i-1000^>nul^&set $PATH^&exit !$c!
 ↑ これは1行なのでメモ帳的には下の感じ。
cmd/q/v:on/k prompt ^^^> ^&path=%path%;^&path=!path:;;=;!^&for /L %i in (1001,1,1023) do set/a $i=%i^>nul^&set $i=!$i:~1!^&for /F "delims=;" %p in ("!PATH!") do set $PATH!$i!=%p^&set path=!PATH:%p;=!^&if not defined PATH set/a $c=%i-1000^>nul^&set $PATH^&exit !$c!


more /ちょこっと解説
[PR]
by bucmacoto | 2018-03-04 04:58 | &Tips;&code; | Trackback(7) | Comments(0)
砂場遊び /3.4 (ちょこっと後片付)
2018年 03月 04日
実は先日投稿のソースにはバグがある。(翌日にちょこっと手直し済み)
ワンライナー側ではなく、それを呼び出して >$msgbox.vbs としているところが不具合だ。

秒数が1桁だとポップアップしないので、スクリーンショットを撮るときは 09 のような形式で無理やりに動作させていた。
これは、リダイレクト記号の直前に1桁の数字があると、それを入出力デバイス番号とみなすという仕様による。
コマンドやパラメータ間を空白で区切るのがDOS系OSの基本流儀。なのではあるがこのリダイレクト記号直前のデバイス番号については、挙動がおかしいことに気づいた後しばらくして理解した。(ちなみに リダイレクトインの直前デバイス番号は 0< に、リダイレクトアウトの標準出力は 1> 、標準エラー出力は 2> になる)

そしてもう一つ、こちらはごくちいさなパフォーマンス劣化に過ぎないので実害はごくわずか。
vbscript(ファイル=$msgbox.vbs)を実行させるために、cscript.exe から実行させていたが、これは wscript.exe から呼び出す方が、僅かに早いようだ。
(なんとなくCUI=文字操作側のcscriptの方がキビキビ動きそうなものだが、GUIを操作するwscriptオブジェクトだからそちらが本職なのだと憶えよう)

上半分はwscript(9秒のタイムアウトで9.75秒)、
下半分はcscript(9.80秒)。
c0062295_21055058.gif


一方で、手直し前のコードだとタイムアウト設定のつもりの 秒数=9(第4引数) が、(ありはしない)デバイス番号と解釈されているらしく消えている。
そのため秒数設定が空文字となって、ノータイムで戻っている = 戻り値(エラーレベル)が、0 となっていることでまともに動いていないことがわかる。
上半分はcscript(ノータイムの戻りで1.72秒)、
下半分はwscript(1.70秒)。まあほとんど誤差に近いが、上下逆にしても同じ速さ順だから、違いがあるのは間違いではないようだ。
c0062295_21092064.gif


ところで、このリダイレクト記号直前の数字だが、1> は標準出力先を、2> は標準エラー出力先を切り替えるときに使用すると説明される。
となると、0> ではどうなるか、3> や 4> ではどうなるかを確かめずにはいられないのが人情ではないだろうか?
(まあ、痴的好奇心と言われてしまえば、これはそうなのかも)


連続する変数を代入する場合に重宝するのが、for /L の文だが、この(変数代入をする)for や (条件分岐判断をする)if 文は、果たしてコマンドだと言えるのだろうか?
確かに、30年も前のMSDOSリファレンスガイドにもコマンド一覧に載ってはいた。けれども、次の二点で他の内部コマンドとは毛色が異なっている印象がある。
  • for/L とか if/I とかのように、直後に(空白を挟まずに)/スイッチのパラメータをつけるとエラーとなる。
    (set/a とか dir/s などではスイッチ直前が空白でなくとも動作する)
  • call if とか、call for のような、callで呼び出して実行することはできない。
    (call echo.〜〜 や、call set 〜=〜〜 のような実行方法が、ほとんどのコマンドで可能なのとは対照的)
そんなことを確認するのも含めて、遅延展開を有効にした cmd.exe 下で実験してみた。
(ほんのすこし前に気づいたのですが、cmd/v:on/k prompt ^^^> ^&title enabledelayedexpansion<リターン>とやると、遅延展開を有効=バッチ内で setlocal enabledelayedexpansion を宣言中と同じように !変数! の形式が使用できて、プロンプトとコマンド窓タイトルでどのような設定状況か混乱しない砂場遊びが可能なのですね)

more リダイレクト記号直前後の数字
[PR]
by bucmacoto | 2018-03-04 04:03 | &Tips;&code; | Trackback | Comments(0)