MS-DOS
のノくッチプログラム
t
支j
去
中 村 邦 彦
I はじめに 昭和62年末から何冊かMS-DO訟のパッチプ。ログラムに関する書籍が続け [1][2][3] て発売された。それらの著者のうちの1
人, ビート・バテヴェーレスは彼の著書 の中で次のように述べている。 『ノミッチ・ファイル・ユティリティは,書いたり保持したりするのが最も簡単 なタイプのプログラムですが,皮肉なことに, MS-DOSのための洗練された パッチ・ファイルを書くのに必要な手法は,あまり知られていません。』 このような状況になっているのは, MS-DOSのコマンドプロセッサ COM-[4] MAND
.
.COM に欠陥があり,し、くつもの版があること,マニコプルが悪く,説 明が誤っていたり不十分であったりすること, UNIXのSHELLを知っている 者にとっては, MS-DOSのCOMMANDCOMは陳腐にみえたことなどの理 由から,真剣にパッチプログラムに取り組もうという人が現れにくかったので はないかと思われる。しかし文献[1 ]を見たときに「これなら使える」とい う感触を持ち, MS-DOSの使い勝手の改善に役立ててみようと考えた。 米国ではすでにOS/2が出荷されでおり, 日本版も間もなく出荷される予定 とのことであるが, 80386と80286は,今のところ速い8086として使われてい るだけのようであるし, MS-DOSはまだ当分の間,使用されるであろう。ここ でパッチプログラムの技術を論じることは,決して無駄なことではなし、。 本稿では,まず,メーカーから提供される説明書だけではわかりにくいパッ チプログラミングの,一歩進んだテグニックを解説し,次にパッチフ。ログラム ( 1) MS-DOS, OSj2,は米国マイクロソフト社の製品である。 (2) UNIXは米国ベノレ研究所の開発したオベレーティングシステムである。-86- 第61巻 第2号 240 を有効利用するための,いくつかの新しいサポートプログラムを紹介する。最 後にそれらを利用したいくつかのパyチプログラムを発表する。 なお,本稿におけるプログラム開発に当たっては,ハードウェアとしてはN
EC
製パーソナノレコンビュータPC-9801
シリーズ(主記憶6
4
0KB)
にノ、ード ディスクとラムディスクを増設したものを,OS
はMS-DOS3
1
0
,アセンブラ はMASM40
,C
言語はマイグロソフトC40
を使用した。その他,アスキー のS
o
f
t
w
a
r
eT
o
o
l
s
1
および2
も一部使用した。 II 市販プログラムに見られるパッチのテクニック ここではまず既存のノミッチプログラムにおいて使用されているテクニッグを まとめておくことにする。 (1) ユティリティプログラムを利用する まず前提となることは,既存のユティリティプログラムをよく知っておくこ とである。本稿でもMS-DOS
に付属しているユティリティの他に,アスキー ツールの一部を使用している。そのすべてを揃える必要はないが,文献[1
]
に述べてあるサポートファイル程度は用意しておき,その機能をよく理解して おく必要がある。 (2) エスケープシーケンスを利用する エスケープシーケン支とは, この場合,画面への出力における種々の操作命 令である。PEMET
ユティリティはこれを頻繁に,かつ上手に利用している。 表示色を変えたり,見苦しい出力を見やすく整えるためには,なくてはならな い知識である。例えばPEMET
パッチファィ定は,以下のように始まることが 多い。ECHO o
f
f
ECHO
~ [[2A~ [[2M~[[32m
(3) MASM,マイクロソフトCは米国マイクロソフト社の製品である。 (4) 以後アスキーツールと記す。 ( 5) エスケープシーケンスについては文献 [5Jに解説がある。 ( 6) 文献[1]にあるパッチプログラムのこと。241 MS-DOSの ハ ッ チ プ ロ グ ラ ム 技 法 -87-ここで
1
はl
バイトのエスケープ文字コードを表わす。[
[
2A
はカーソル を2行上へ移動させることをご[[2M はカーソル以下の2行を削除すること を,ハ[
[
3
2
mは以後の出力のカラーを緑色にすることを指示するコードである。 その効果のほどを確かめるために 2つのバッチファイルとその実行結果を示 す(Lis
t
1)。
Listl..エスケープシーケンスの働き BL BATの内容 ECHO 01f ECHO aaaaaaaaaaaa ECHO bbbbbbbbbbbb Bl..BATの実行結果 <F:警>B1 くF:警>ECHO off aaaaaaaaaaaa bbbbbbbbbbbb くF:¥〉 B2..BATの内容 ECHO off ECHO ^ [[2A、[[2M'[[32m ECHO aaaaaaaaaaaa ECHO bbbbbbbbbbbb B2.. BATの実行結果 くF:警>B2 aaaaaaaaaaaa bbbbbbbbbbbb くF:Y>B2. BATの実行結果の方はECHOoff の行がなくなっている。これは~.ß.表
示された後,消去されたのである。なおプロンプトの形が変わっているのは, 環境変数PROMPTが$e[36m$1$p$g$e [33mと設定されているためである。 2行上に移動して2行削除しているはずなのに,実際には1行しか削除され ていないが,これはB2..BATの2行自のECHOのあとにCR/LF(キャリッジ リターン/ラインフィード〉が出力されてしまうためである。 そのほか,エスケープシーケンスにより,カーソル位置と表示文字の属性(文 字の色など〕を~ß.保存しておいて,別のメッセージを割り込ませたのち,元 の状態に復帰するなどということも可能になる。
(
3
)
環境変数を利用する。 何かプログラムを書こうとすれば,その中で一時的に何かを記憶しておくと ころ(変数〉が必要になる。ところがバッチプログラムにおいては,そのよう な機能が用意されていない。そこでシステムの環境変数を利用することを考え88- 第61巻 第2号 242 る。環境変数はシステムが定義しているものの他に,ユーザが自由に定義して 使用できるものがある。
PEMET
ユティリティを例にして解説する(Lis
t
2
)
。 List2環境変数 DSKBAT"BAT文献(1)52買より抜粋 ① SET fil=帥 ② IF NOT "%fil%"=="%O" GOTO overflow ③ : overf low Echo^草^[[A供[[ち;31圃ABORTED!、[[皿 Environmentoverflow"[[32皿 GOTO end ④ FOR %%p in(fil0)DO SET %%p= ここで……は,プログラムの一部が省略されていることを表わす(以下同じ)。 まず①で血という環境変数を定義し,それに仮パラメータ %0の値を設定し ている。%0はこのプログラムが呼び出されたときに,自分自身のファイル名に 置き換えられる。 次の文はその白1~こ %0 が正しく代入されたかどうかを検査している。これは 環境変数の領域には限度があり,その限度を越えていないかどうかを検査して いるのである。不幸にして越えておれば③へ行ってメッセージを表示して処理 を中止する。 最後にこのプログラムで定義する環境変数は,このプログラムが終了すると きに全部消去しておきたい。それを④で行なっている。inの後ろの括弧の中に, 消去したい環境変数名をすべて書いておくと,この文でそれらがすべて消去さ れる。 なお,I
F
文の中で比較する文字列を引用符"で閤んでいるが,これは環境変 数や仮パラメータをそのまま比較した場合,環境変数または仮パラメータが値 を持たないときには ifxxxx
=
g
o
t
o
のような文ができてしまし、,エラーになるからである。この場合は,引用符"は 特に引用符としての機能はなく,次の文はすべて正しく機能する。 if "%fil% = "%0れ if%日%"
=
%0"243
MS-DOS
のパッチプログラム技法 8 QJi
f
&%出%&
=
&%0&
ただし文字列の中にリダイレクトとパイプの記号(<>
1
)
が含まれるとき は引用符で囲んでおく必要がある。 (4) パラメータの解析 パッチプログラムに渡されるパラメータのうち,ファイル名を指定するよう なものは問題ないが,プログラムの動作の詳細を指定するオプションの場合は 士夫が必要である。例えばUNIX
風 にh-m-n
をオプションとして指定でき るようにしようと思えば,大文字小文字の別,-mn
のような組合せを許すかど うかなどが問題となろう。L
i
s
t
3
で は も ま た は-Hは単独で使用され n,m とは同時に指定されるこ とはないと仮定している(-hはhelp,すなわち使い方を表示させたいときに使 用するオプションである。 )nまたは mが単独で使用された場合は③と④で検出 される。まとめて指定された場合は⑤で検出される。 m, nが別々に指定され List3パラメータの解析 LISTFILE“BAT文 献 [1 ]68頁より抜粋① FOR問h IN (-h -H) DO IF "%I"=="%%h‘GOTO he lp
② FOR 耳目p IN ( 皿o ) DO SET %%p=
:MNTEST
③ FOR開 田 IN (-m -M) DO IF"耳1"=="耳目皿"GOTO setm
④ FOR %%0 IN (-0 -N) DO IF "%1"=="問o GOTO seto
⑤ FOR %%0 IN (-mo -0阻 -MN -NM) DO IF "%1"=="似0" GOTO setllo IF "%1"=="" GOTO abort w w w A U V A V A V I A -a f f f F 且 , a , E ρ l u a u a z w v v v A V A V A V A H V A H V A U 叩 1 中 i 中 A A H V A H V A U n u n u n u m 胤 n u n u -= = = = = " " " w h A 河 + , む M w 伽 均 m + 且 も w w h + . む w 備 鵬 e A o u n M e d n “ e J d w w “ 刈 何 aiUMν-h 泊 白 ' L w ν h a l U v " + ι 相 " & . v " + ι n U 圃 . n “ 怜 u n “ " 刷 n M n u E = T B = T 圃 = = T E E 刷 圃 0 T 目 0 T H 圃 白 0 T F し ・ MmmmpMXAUmm 首 mnFOUM 畑 町 R F M X ︽ U o v ・ 中 且 m i y 且 T a 中 且 T a y 且 T A m -中 A 中 且 v i 中 A n 民 ・ 軒 E 軒 巴 F F n n A U 軒 畠 わ ERFnn の UFEnzpE ゎ rnn の υ nr-QMQUI-n 九 M G w n h u R U T i n b n h u R M R M q M 官 l n m w n b
...•••••
⑥ ⑦ ③244 第2号 第61巻 -90ー る場合もあり得るので,⑥⑦⑧で仮パラメタ全体を
SHIFT
させてから,③へ 戻って同様の処理をする。 著者のメテヴェーレスはここで,.これ以上のテグニ yクもありますが,考え List 4に筆者の考えた方法を紹介しておく。 られますか?J
と書いているので, n r ν h m w 刈 争 E u a b e o A V ‘L n v eb n y w A VA-一 -' E A NA t - -) U R M m M m w n n 阻 血 n u u m M n M M m円 圃 -( 町 民 I P 睡 H W A n u m 嗣 n u
・ 岨
w為
-ゐ a 、 ‘ E h w w 柑 +ιv&E n“瓜品 e"e"ee の υ s e s d " e s o e so Er.:.::: List4パラメータの解析(別解) オプションが大文字で与えられたときにうまくいくの このようにした場合, かどうかが心配になるが, ラベルの大文字小文字の区別はしないらしい。 ノレープのカウントの仕方 (5) それがl命令で パッチプログラム中で同じことを何度か繰り返したいとき, すむ場合はf
o
r
%
%
pi
n
(
1
2
3
4
5
6
)
d
o
とすればよし、。 複数の行に渡って繰り返したいときは、変数に初期備を代入しl固とおるた びに1
を加えて行きたいところであるが、パッチには代数加算の機能がなし、。 メテヴェーレスのテクニックをみてみよう (List5)。 List5繰り返し制御 DIRCOM.. BAT文献[1]61頁より抜粋 SET cnt= :CONTROL (inner loop) SET cnt=I%cnt% IF %cnt%==I SET typ=COM IF %cnt%==II SET typ=EXE IF %cnt%==III SET typ=BAT IF %cnt%==IIII GOTO finish GOTO CONT茸OL :FINISH SET cnt= ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨245 MS-DOSのパッチプログラム技法 91-彼は,環境変数に文字列を設定できることを利用して,ループを l度目るた びに文字Tを追加している。そしてループカウンタ
c
n
t
が'IIII'になったとき, このループを抜け出すようにしている。(
6
)
パグチのチェイン あるパッチプログラムから,別のパッチプログラムを呼び出して使おうとし て,単にノミッチファイル名だけを書くと,確かにそのノミッチプログラムは起動 されるが,新しいパッチプログラムの実行が終了しても,制御はもはや呼び出 し元へは帰ってこない。制御を呼び出し元、へ戻したければ,COMMAN
D
.
COM
と jCスイッチを利用する必要がある。COMMAND
jCパッチファイル名 このやり方は第1のノミッチプログラム(親)で第2のノミッチプログラム(子) を 作 成 し そ れ を 実 行 後 , 第1のパッチプログラムに戻って不要になった第2 のパッチプログラムを消去できるので便利である。しかしながらこの方法が利 用できない場合がある。それは子ノミッチの中で環境変数を定義したい場合,デ バイスドライバを追加するADDDRV
ュティリティを使いたい場合などであ る。 環境変数の場合は,環境変数はあるプロセスに固有のものであり,子プロセ スで新しい環境変数を定義しても親の環境変数にはならない(環境は親から子 へと渡すことはできるが子から親へは渡せない〉。文献[2
]では,rMS-DOS
のパージョン番号を環境変数に登録する」という処理を取り上げ、て,ここらの 問題点を解説している(
L
i
s
t
旬。 List6パッチチェイン1 setver.. bat文献[2]VoI2.83頁 ① echo 01f② echo set version=> %0$.$$1
③ ver word -s tail -1 > %0$.$$2 ④ paste -d"初 "%0$.. $$1 %0$.. $$2 >刑事..bat ⑤ rll %0$.. $$1 %0$.. $$2 ⑥ 刑 事 ここで行なっていることは②④で
s
e
t
v
e
r
s
i
o
n
=
3
.
.
1
0
-92ー 第61巻 第2号 246 という内容のパッチファイル
s
e
t
v
e
r
$ b
a
t
を作成し、⑤で中間ファイルを消去 して,⑥でそれを起動しているだけである。⑥をcommand/
c
%
0
$
として戻っ てきてからs
e
t
v
e
r
$ b
a
t
を消去したいところであるが,それができないことは 先に述べたとおりである。 ところでもうひとつ,たかが'
s
e
tv
e
r
s
i
o
n
=
3
.
.
1
0
'
という1
行を作成するの に 中 聞 に フ ァ イ ル を2
つも作成しp
a
s
t
e
まで使わなければならないとは,し、か にもおおげさである。これら2
つの問題をメテヴェーレスは次のようにして解 決している (List刀。 List7バッチチェイン2 SAVEDIR BAT文献[1]100頁より抜粋 ① IF"耳1"==" de1 ete" GOTO er ase ② TYPE a:警savedir“dta >>a:干oldirbat ③ CHDIR >>a:Voldir.bat ④ ECHO SAVEDIR delete >>a:Voldir伽bat GOTO end ⑤:ERASE ⑥ ERASE a:Voldir, bat ECHO Returned to directory: CHDIR :END このプログラムは、c
u
r
r
e
n
td
i
r
e
c
t
o
r
y
を保存しておいて,後で簡単に戻って こられるようにするためのものである。ファイノレSAVEDIR
リDTA
は前もって エディタ等で作成されているファイルで,その中身は'CHDIR
Z'である。 Z はファイルの終わりを表わす記号である。この行は,MS-DOS
の通常の行の終 わ り で あ るCR/LF
が な い 形 に な っ て い る 。 こ れ で 新 し い パ ッ チ フ ァ イ ルo
!
d
i
r
b
a
t
の内容は②@④によってCHDIR p
a
t
h
name
SA
VEDIR d
e
!
e
t
e
となる。ただしp
a
t
hname
は実際にはその時点のc
u
r
r
e
n
td
i
r
e
c
t
o
r
y
へのp
a
t
h
が書かれる。2
行目のSAVEDIR d
e
!
e
t
e
は,このバッチプログラムが起動され た後,自分自身を消去させるためのものである。s
a
v
e
d
i
r
れb
a
t
の①により⑤へ飛247 MS-DOSのノ〈グチプログラム技法 -93 んで⑥で oldir batが消される。文献[2 ]の著者は,この方法に気がついてい ないようであるが, この方法を使えば,あるパッチプログラム中で作った別の パッチプログラムを,使用後自動的に消去することができる。 ただし,もう一つのテクニックの方は,このようなやり方を使うごとに,CRj
LF
のない行をもっファイルを用意しておかなければならないので感心しな い。この問題の別の解決法については次節で提案する。 III パyチのためのツールの開発 (1)e
c
h
o
の改良MS-DOS
の内部コマンドにECHO
がある。ECHO
には,パッチプログラム内の命令行を, コンソーノレにエコーバ yグさせるかさせないかさと設定する役割 と,
ECHO
のコマンド行に書かれた内容を標準出力に書き出す機能がある。後 者の機能はノミッチの中で小さなファイルを作成するのに利用できる。ところが 先にみたように,ECHO
は文字列の最後に常にCRjLF
をつけ加えるために,I
行の命令文の前の方の1
部を書き出すことができない。そこでCRjLF
も含 め た 特 殊 文 字 の 出 力 を 制 御 可 能 なECHO
プ ロ グ ラ ム を つ く り こ れ にECHOES
と名前をつけた。 もともとは,行の最後にCRjLF
を含まない行念出力できるものが欲しくて 考えだしたものであるが,メッセージの任意の位置にCRjLF
を埋め込むこと ができるようになったので,一度に複数行の出力も可能になったことから,ECHOES
という名前にした。ECHOES
の仕様を簡単に述べると iコマンド行 に書かれた文字列を標準出力に出力する。その際特殊文字をエスケープシーケ ンスを用いて記述できるようにする。ただし引用符"は無視するりとでもなろ う。引用符"を無視するのは,COMMAND.. COM
が区切り記号としている一 部の文字をメッセージの一部として使用するためには,その文字列を引用符" で屈まなければならなし、からである。特殊文字のエスケープシーケンスはC
言( 7) SA VEDIR BATの中で作成されるOLDIR BATはユーザーが起動するようになっ
-94 第61巻 第2号
語の規則に準じた(表1)。
これを用いれば先の List6の② ④は
echoes set version
=
>%0$
, batver I word -s I tail
-
1
>
>%0$"
batと書き直すことができる。 List
7
の②は echoes chdir>
>
a :¥oldir "bat とできる。 248 引用符を除いて表示する効果は,後出のList8のようにリダイレグト記号や パイプ記号を含むバッチプログラムを簡単に作成できることで確認できるであ ろう。 更に副次効果として,エディタを使用しなくてもコンソーノレやプリンタに特 殊文字列を送出できることになった。プログラムは,次のINQに含まれるので 省略する。 なお本家UNIXの ECHOについても種々の議論があったが,現在のものは ここに述‘べたような機能を持つようになっている。 (2) ユーザーの応答を取り込むプログラム ノミグチプログラム中で,特別なプログラムを使わずに,ユーザーの応答を取 り込むことは不可能ではないよ]やはりそのためのプログラムを用意する方が 表1 ECHOESの エ ス ケ ー プ シ ー ケ ン ス ¥n line feed ¥t tab ¥b backspace ¥r carrige retum ¥f form feed ¥¥ ¥ ¥q ¥xhh hexadecimal ¥ddd octal negrect (8 ) 文献[5]の121-124頁に紹介されている。249
MS-DOS
のバッチプログラム技法 -.95-よい。 PEMETュティリティでは,ユーザーの YesjNoの選択を取り込むため
[3]
のUSER.COMというプログラムを,別の例では,選択されたメニューの番号
を取り込むためのINPUT..COMというプログラムを用意している。そこで, この両者の機能を合わせ持つINQ“EXEjINQ COMを作成した。
INQはコマンド行に書かれたメッセージを表示し,指定された文字の応答を 待ち,応答があればそれを終了コードにセットして終了する。指定された文字 以外の文字を入力すると警告音を鳴らして再入力を求める。応答文字の指定方 法は, コマンド行の先頭に[
J
で囲んで指定する。これはUNIXのReguler Expressionにおける 1文字の表現法に準じた。その規則を表Hこ示す。表示す る文の方は先のECHOESと同じ規則にした。そのため応答文字列の指定を省 略した場合, INQはECHOESとまったく同じ働きをする。最初はC言語によ るプログラムを作成したが,アセンブラ語で書き直してみたところプログラム サイズが500バイトたらず(Cで作成したときの約16分の1)になったので, そちらの方を掲載しておく(Lis
t
10)。ユーザーの応答を取り込む部分を除けば ECHOESになる。 (3) パッチプログラムを結合分離するプログラム パッチプログラムの技術を身につけて, どんどんパクチプログラムを作成し てL、くと,必然的に小さなプログラムファイルが増えてくる。ハードディスク のような大容量の補助記憶装置を利用している場合, これらの小さなファイノレ は,補助記憶の領域の利用効率を著しく低下させてしまう恐れがある。そこで 文献 [1,
]
[2Jのノミッチファイルについて具体的に調べたものが表3と4で ある。 表2 応答文字指定規則 [ ]で囲んで指定する 1文字ずつ指定する [YN] 範闘で指定する [1-5] 1, 2, 5 組み合わせて指定する [O-9A-F] 0 - 9お よ びA-Fの内の1字 任意の1文字 [.] ただし,大文字と小文字の区別はせず,返す値は大文字で返す-96- 第61巻 第2号 250 表3 パッチファイノレの大きさ ファイノレ数 サ イ ズ の 合 計 メ デ ィ ア ン 平 均 サ イ ズ 標 準 偏 差 72 19000 167 263 9 218 6 PEMET 48 48966 938 1020 1 741 7 表4 使 用 効 率 ファイ 正 味 の 占有領域と有効利用率 ノレ数 大 き さ 1MB FD 20MB HD 40MB HD TOOLS 72 19KB 72KB 8x72
=
576KB 16 x 72=
1152KB 264% 33% 165% PEMET 48 49KB 76KB 8x48=
384KB 16 x 48=
768KB 658% 127% 638% これをみれば, PEMETュティリティとアスキーツーノレで、は,ファイルの大 きさが随分異なっていることがわかる。これは両者の聞にプログラムの書き方 において明確な違いがあるからで,前者の方にはパラメータチェック, エラー チェック,ヘルプメッセージがしっかり組み込まれているためである。 MS-DOSの 補 助 記 憶 の 領 域 割 付 は ク ラ ス タ を 単 位 と し て 行 な わ れ て い る が,これが 1MBフロッピーディスグの場合は1K B, 20 M Bハードディスクの 場 合 は8K B, 40 M Bハ ー ド デ ィ ス ク の 場 合 は16KBとなる。したがって40 M Bハードディスクの場合は,たった 1バイトの大きさのファイルであっても 実際には16KBの領域を占有してしまうことになる。表4からわかるように, 40MBハードディスクの場合ツールで 1134K B, PEMETで734K Bが無駄に なってしまう。 バッチファイノレは,実行速度を速めるために,ハードディスクまたはラムディ スクにおいて使用することが望ましい。ところがハードディスクにおけば領域 の無駄使いになるので,保存はハードディスクにひとまとめにしておいておき, システム起動時に分解してラムディスクにコピーしておくことにすればよし、。 このように考えて作成したのが,パッチプログラムを連結する BCATとそ れを分割する BSPLITである。連結されたノミッチファイノレの構造は, 1つ1つ251 MS←DOSのノミッチプログヲム技法 -97-のファイルの,最初に
2
個の@記号に引続きファイル名を置く行を先頭にして, 最後にCTRL-L
(16
進表現でo
C)
を付加したものにすることにした。いずれ もC
で書いたが,連結するのは手聞を厭わなければエディタでも可能であるし,L
i
s
t
8
のようなパッチプログラムでも可能である。BCAT
,BSPLIT
共にプロ グラムとしてはありきたりのものであるので, Cによるソースプログラムリス トは省略する。 List8パッチファイルを連結するバッチプログラム echo off echo"[[A"[[K-[[A if "%1"=="" goto help fo1'%%h in ーh-H)do if "%1"=='耳目h" goto helpechoes "echo off干necho "[[3A-[[3M%%lin")%ram%戦0'.bat
echoes "echo 唖申%%1>)%%2干ntype耳目1))見詰2干nechoes"1>)耳目2干n">)%ram%干児0'..bat fo1'耳目p in (%2 %3 %4 %5 %6 %7 %8 %9) do co皿mand/c %0' %%p %1 del %ram見守%0'.bat echo^ [[A^[[K"[[A goto end :help
echo Batch file concatination progra阻
echo Syntax: %0 destination_file source_filespec(s)
echo source files are in current directory
echo globals are allowed in source_filespec(s)
:end なお,
PDS
においてよく使用されているPKware
社のファイル圧縮プログ ラムPKARC
により圧縮すればもっと効率よく圧縮できる。PEMET
の方は32υ2KB
に,TOOLS
の方は164KB
にすることができるが,今の場合圧縮プ ログラムを使用することによって救われる領域は問題にならなし、。I
V
使用例 (1) 日付と時刻を表示させるプログラムシステムを立ち上げるとき,
AUTOEXECBAT
にDATE
とTIME
コマン ドを含めておかないと,システムカレンダーのチエグクができず,間違った日 付 の フ ァ イ ル を 作 成 し て 困 っ た こ と が 何 度 か あ っ た 。DATE
,TIME
をAUTOEXEC.. b
a
t
の 中 に 含 め れ ば よ い の だ が , こ の2
つ の コ マ ン ド は ユ ー-98- 第61巻 第2号 252 ザーの応答を求めてくるために, 日付が正しい場合でもリターンキーを押して やらないと次の処理へ進んでくれない。そこで日付と時刻の表示だけをさせる ようにしたのが
L
i
s
t 9
のプログラムである。これはアスキーアールの中のKTIME
を使えばできるのであるが,エスケープシーケンスの使い方,バッチ ファイルの中で別のファイルを作成して,それを使用後に消去してしまう例と して作成してみた。 List9日付と時刻jを表示させるプログラム echoes警n>%ram見守cr1 f..$$$ dateく%ra圃百警crlf“$$$ echo'[[2A timeく%ra田%¥cr1 L $$$ echo内[[A^[[K^[[A del %ram克¥*凶$$$ 最初の行でCR/LF
だけのファイルを作成しているが,MS-DOS 2
.
.
1
ならe
c
h
o
>%ram%
¥c
r
l
f
.
.
$
$
$
(
e
c
h
o
のあとに空白が2
個ある),3
れlならe
c
h
o
>%ram%
¥
c
r
l
f
.
.
$
$
$
とすることによりe
c
h
o
e
s
を 使 わ な く て も す む 。 な お こ れ はAUTOEXEC
BAT
に組み込んで使うことを想定している。 (2) 一太郎を起動するプログラム 一太郎のv
e
r
s
i
o
n3
.
.
0
はプログラムサイズが大きく,デバイスドライパーや メモリー内常駐型のプログラムを組み込んだまま, うっかり起動するとハング アップが生じ,システムリセットを余儀なくされることがある。そうでなくて も,日本語入力プロセッサとしてATOK
以外のものを使用しているときは,一 旦そのドライパを取り除いてからATOK
を組み込むことをしなければなら ない。これをパァチプログラムを利用して行なおうとはだれしもが考えるであ ろうがこれは簡単にはできない。 実行したい手順は,簡単に書けば次のようなものである。d
e
l
d
r
v
(0) 一太郎, ATOKはジャストシステム(株)の製品である。253 MS-DOSのパ yチプログラム技法 -99 adddrv atok dev JXW これを手操作で一つづっ行なえばもちろんうまく行くが, これと同じ内容を パッチファイルにして実行しても, うまく行ったりいかなかったりする。そし てさらに不思議なことに,このパッチプログラムを2つ作ってチェインすると うまく行くらしし、。 そこで
CHKDSK
でフリーメモリーを調べてみると,最初のDELDRV
で開 放したはずの古いデバイスドライパの領域が,その時点ではフリーメモリーに 加えられていないことがわかった。これはMS-DOS
のメモリー管理の方法に 起因するものであると考えられる。ノミ yチを起動するときにはフリーメモリー の最下位に何らかのメモリーが確保されるため,そのノミッチの中でそれより低 いアドレスの領域が開放されても,すぐに使用可能にはならないと考えれば説 明がつく。また2
つのノ yチをチェインすると2
番目のノミッチのための領域 がメモリーの最下位に改めて確保されるため, フリーメモリーが大きくなって 一太郎が起動できるようになることがわかった。たかが一太郎一つを起動する ために2
つもパ yチファイルが必要というのはおもしろくないし,プログラム 管理上も具合いが悪いので,それを一つにまとめることを考えた。あまり余計 なことをしなければList11のようなパッチプログラムを1つ作ればよし、。 まずパス 1で古いデパイスドライバを切り放す。この時点ではまだフリーメ モリーは増加していなし、。ここで, このノミッチプログラムを再び呼び出すよう な新しいノミッチを作成し,それにチェインする。 2回目に呼び出されるときは, パラメータによりパス2
が指定され,ATOK
が組み込まれ,引続き一太郎が起 動される。最後に一太郎の終了後,一時的に作成されたファイノレをす町ベて消去 して終了する。 この一太郎を起動するバッチプログラムは,し、くつかの間題をかかえている。 (11) 文献[3 ] pp.126-128に日本語フロントプロセッサの動的切り替えのためのプログラ ムが載せてあるが,そこではDELDRVとADDDRVを単純に連続して使用している。 (12) この事実は宍戸栄徳氏(香川大学経済学部管理科学科〉に教えていただいた。-100- 第61巻 第2号 254 まずハードディスクやラムディスクを含むシステムでは,そのとき,どのサブ ディレクトリにいても一太郎を起動できて,終了後はもとのディレクトリに 戻って来たい。
ADDDRV
に必要なATOK
の定義ファイルを別に作っておく のは, ファイル管理上からも,ディスクスペースの有効利用という点からもお もしろくなし、。また一太郎にはテキストファイルを直接指定して起動する方法, さらに/
S
というオプションもある。以上の点を改良したのがLIST1
2
のプロ グラムである。ただし環境変数ram
にはラムディスクのドライブ名が,hdには ρ ードディスクのドライブ名がセットされているものとし,一太郎のシステム はハードディスグのサブディレクトリ¥jxwにあるものとしている。 (3) デバイスドライパを組み込むためのノミッチプログラム プログラミングテクニックとしては先の一太郎の起動プログラムと同じであ るが,デバイスドライバを組み込むためのパッチプログラムも作成した(Lis
t
13)。
V むすびMS-DOS
の,付属の説明書だけではわかりにくいノミッチプログラミングの テクニックのうち,重要と思われるものを取り上げて解説し,いくつかの新し いテクニックを加え,それらを使用してMS-DOS
の操作環境を改善すること ができた。MS-DOS
は今日まで,公表されたもの,されなかったものも含めて,次々と 改訂されてきたが,今後は主力がOS/2
に移っていくために,MS-DOS
の大き な変更はないものと思われる。そういう意味では,かえって落ちついてプログ ラム開発ができるともいえなくもなし、。MS-DOS
は,パーソナノレコンビュータのための,シングルユーザー,シング ルタスクのOS
としてはよくできたOS
であり,いろいろ欠点も指摘されてい(
3
)
HISTORY COM
,SA
VHIS COM
は 岡 俊 行 氏 ,RMHIS. COM
はK
o
m
a
i
氏の作255 MS-DOSのパッチプログラム技法 -101 るが,それはそれだけよく使用されている証拠でもある。工夫しだいでまだま だ操作環境を改善できるであろうし,そのための努力も必要である。 参考文献 [ 1 ]ピーいメテヴェーレス, rMS-DOSパッチ・プログラム集j,技術評論社,昭和62年11 月。
[ 2 ]アスキー書籍編集部, rMS-DOSを256倍使うための本」アスキー出版局, Vol 1, Vol
2,昭和62年12月。 [ 3]藤田英時, rMS-DOSまかせの実用バッチファイノレ集j,ナ Yメ社,昭和63年4月。 [4] rMS-DOS 3.1ユーザーズリファレンスマニュアノレj, 日本電気。 [ 5 ]ビーいメテヴェーレス, rMS-DOSファイノレ整理学j,アスキー出版局,昭和61年 4月。 [ 6 ]石田晴久監訳, rUNIXプログラミング環境j,アスキー出版局,昭和60年10月。 [ 7 ]山田祥平,安田孝弘他, rMS-DOS便利グッズカタログj,技術評論社,昭和63年5月。
102- 第61巻 第2号 256 l i s t 1 (1 1 nq.. com call ginqst c all skpblk t i t 1 e 1 nq併asm l刷。
.
otloop: Constants cmp al, CR Je extlop BELl e qu u7h c mp al, '¥' BS equ u8h J e doesc TAB equ u9h cmp al, FF equ Och J e doquot LF equ Oah default CR equ Odh putalRUB equ 7fh nxloop: nextch
Jmp otloop
Macros '
doesc: c all escseq
nextch macro Jmp otloop
lodsb ,
end田 doquot: . j mp nxloop
,
putal 皿aero extlop: call 1 nq
血ov dl, al
mov ah, 2 Terminate Process
int 21h mov ah,4ch
endm int 21h
皿aln e ndp
putch 皿acro char
push ax escseq proc
mov dl.char nextch 国ov ah, 2 switch(al) int 21h E田p a 1.'n ' pop ax J e donl endm cmp al.'t' J e dotab putdl macro cmp al, 'b' push ax J e dobs mov ah, 2 cmp al.'r' int 21h J e docr pop ax cmp al, 'f' endm J e do ff cmp al, '¥'
code seg皿ent J e doen
assu皿ecs:code, ds:code cmp al, 'q'
assume es:code, ss:code J e dodq
cmp al.'x' org 81h J e dohex cmdl i n label byte default c a 11 isoctal org 100h Jnc escsl ' c all putoct mal n proc far escsl: ret mov si.offset cmdl in ; cld donl: putch CR nextch putch LF call skpblk Jmp escnx
257
MS-DOS
の パ ッ チ プ ロ グ ラ ム 技 法 dotab: putch TAB)mp escnx dobs: putch BS )mp escnx docr: putch CR )mp escnx doff: putch FF ]皿p escnx doen: putch '守' )mp es c nx dodq: putch '"・ )mp escnx
dohex: call puthex
)mp escfet escnx: nextch escret: ret escseq endp puthex endp skpblk proc c mp a 1. ' jne skpbll nex町ch jmp skpblk skpbll: ret skpblk endp
-ふ ι 。 υ ' i マ t -E , ' A U ・ ' e a o a , , A 2 n w ・ ' A 2 a p 目 、 o n y n u z f 、 E r m e m e -p f ・ ) C r c l 免 n w -t l p -L F L A V A v a d c J ・ 1 1 f'e t , putoct proc xor dx. dx mov cx, 3putocl: call isoctal
)nc putoc2 sub a1.'0' shl dX,l shl dX..l shl dx, 1 add d1.al isoctal endp
-+ , , o υ 1 A n y ' 6。 ,
-A U -- E A C J ' E A & ・ l a E n y o p p t c t d r m 凶 P ﹄ m 刷 ρ 、 , l ρ L n “ n v P E W -' p p -M 伊 a ρ し v ・ ρ L V + も φ L I -1 6b 司A, 。
i g -J U S U J u q i v c o e d -1 ・ 1 nextch loop putocl putoc2: putdl ret putoct endp ishex proc c a 11 )c cmp jc cmp )c cmp )c cmp ishexl: ret ishex2: clc ret ishex endp A H V 'EA A O ρ ﹄ , c d -2 J a L U , 弘 U の L , 唱 1 VAVAVAF し A H V A H V 免 u w V A 令 a ' ﹃ -V A A U 今 , “ e 弘 u ? “ , o o ι u ・ 3 A ' l t A t A a 仇U .,ιuゐ-vvs'''+し・・・・・・&・、 X X S u e -l u l x x x x l u d e -p w a a a p a d d d d d p 弘 U O L n c ' I C 電 i ρ -u + ・ 、 , i & -u n y A U orvx・1EOLυnMEto--'l ‘1 2 1 S a x o φ L e t r o o e a n t r u m c u h h h h d e o u e p x m n C ・ I ・-OSE--2sssssan'ipr -V A 噌' A 。 , “ 今 ‘ J ρ h V A V A V A 弘 U 1 n L U L U + E U -、 ゐ E U ゐ L H U " u u u " u n r n u z n r n u z isd ig i t ishexl ;yes a1.'A' ishex2 ;no al, 'F' + 1 ishexl ;yes al, 'a' ishex2 ;no al, 'f' + 1 103-ginqst procmov di,offset inqstr
C阻p al,' [' jne ginq3 ginql: nextch cmp al, CR je ginq2 c mp a 1. '), je ginq2 call toupper s tosb jmp ginql
-104- 第61巻 第2号 A H V -1 -A U [ v a t n v ρ E v t w v d 弘 U 弘 U A L + L n r xvtd ρ l v n v a I v n u num 附 pa@ し : : t 。 , “ 内 ‘ ノ 自 3 0 U E m u -a u理 由 u n u n u -1 ・1 g o v o g o inq proc mov al.inqstr or al.a1 j z i nq1 ca11 keyin putch CR putch LF inql: ret inq endp keyin proc c a 11 call mov cmp ) e keyinl: ca11 va1id jc keyin2 putch BELl putch BS ca11 conin ca11 toupper jmp keyinl keyin2: ret keyin endp conln toupper si.offset inqstr byte ptr [si].',,' keyin2 conln proc ;read keyboard ah. 08h 21h 阻ov d1. a1 c mp a 1.• )c mov int cmp )c noprln: mov pchar: putd1 ret conin endp noprln a 1.RUB pchar d1. :echo va1 id proc
mov si.offset inqstr
va1 idl: cmp byte ptr [si]. 0
je va1 id5 cmp al.[si] je va1 id4 cmp byte ptr [si]+l,'ー' ine va1id3 cmp al.[si] 258 jc va1 id2 cmp al.[si]+2
jbe va1 id4
va1 id2: add si.2
J皿p va1idl va1id3: inc si i皿p valid1 va1id4・stc ret va1id5: c1c ret va1id endp toupper proc , , 弘 u a ' i Z 唱 i o o ' n r , n r 内 F M ' " u ・ " u ' ' i o ' l o ' i a n w + L 2 a る し 免 u w n u z n y n y v a + し A u m-bmaoen c ・ -c ・ 1xre r . . a 且 し 匂 . i p P • n r n U r E " u u . " ハ v 仇 v φ し & す. ι 旬
inqstr 1abe1 byte
code ends
259 MS白DOSの パ ッ チ プ ロ グ ラ ム 技 法 Listll一太郎を起動するパッチプログラム1 echo off set iil=
。
見
if not '%fil%"=="耳0" goto overflow if "%1"=="" goto passl if"出1"=="pass2" goto pass2 :passl de 1 drv echo %fil% pass2 >>%fil%'.. bat %fil%' :pass2 adddrv atok..dev jxw del %fil%'.. bat goto end : over flow echo、'G***Environment Over凧flow**** :end set fil= List12一太郎を起動するパッチプログラム2 echo off JXWstart up procedure set fi 1=%0 If not "%fll%"=="見0" goto overflow if"%1"=="" goto passl If "%I"=="pass2" goto pass2 :passl echo '[[A" [[K^ [[A echoes set home=> %ram%干%fl1%'“bat cd >> %ra囲拡¥%fl1%'ドbat %ram% cd¥ savhls -h >%ra圃Z¥hls干history..dat 1'llhls >nul de Idrv echo耳fll%pass2 %1 %2 %3 >>%fll%'..bat %fl1%' :pass2 -105-echo device=%hd%警jxw普atok6a..sys /d=%hd% /n=atokL dlc /g=%hd% /I=gaij /e=l>ato k“事$$ echo device=%hd%¥jxw¥atok6b..sys >>atok..$$$ adddrv atok.. $$$ >nul %hd% cd¥jxw fo1'%%p In (-s-5) do If "%%p"=="%2" goto jxw2 jxw %2 goto jxw3 :jxw2 ixw /s=%3 %4 :jxw3 cd警 %ram%106 de 1 %f i 1 % 副.bat de 1 *.. $$$ 第61巻 第2号 history -d%ra田耳干his警ーfb -g -ko -r"L>nul goto end : overfl ow echo "G*** Environ皿ent Overflow **** :end ifnot . %.ho皿e%'=='''' chd for %%p in (fiI)do set %%p= List13デバイスドライパを組み込むバソチプログラム echo off rem add device driver procedure if "%his耳、 set his=yes set fil=%O if not "Ifil%"=="耳0" goto overf low if"11"=='''' goto usage if "%1"=="pass2" goto pass2 :passl echo "[[A^[[K、[[A echo %fil% pass2 >%ram%¥%fil%“・bat : loop1 if..出1..==.... goto exitl 260 for %%p in (pr PR at AT mt MT rs RS血sMS -h-H) do if %%p==%l goto add%%p echo"G*** Para圃eter Error: %1 :usage echo usage echo %0 parameter.引川[-h] echo parameter is one of the followings echo pr:printer at:atok6 echo 狙t:matutake2 rs:rs232c echo 皿s:皿ouse -h:no history goto :end : addpr echo device=%hd%¥dev普print.sys /u >>%ram%警dev..$$$ shift goto :loopl :addat
echo device=%hd%干jxw警atok6a.sys/d=%hd% /n=atokl.dic /g=%hd% /e=I>>lra皿Z¥dev
$$$
echo device=%hd%¥ixw干atok6b.sys)>%ra~%¥dev.. $$$
shift
goto loop1
:addlllt
echo device=%hd%警皿atu警田ttk2.drva: /c05/a6/j5/u/xJ'ハ/mへI./sO/g ))%ram%¥dev.. $$$
shi ft goto loop1 : addrs echo device=克hd%干dev干rsdrv.sys >>%ram%警dev..$$$ shift goto loop1 :addllls
261 shift goto loopl :add-h set his=no shift goto loopl :exitl
MS-DOS
の パ ッ チ プ ロ グ ラ ム 技 法savhis -h >%ra阻耳¥his¥historyゎdat
rmhis >nul
deldrv >nul
%fil%'
:pass2
adddrv %ram見守dev..$$$
if%his%==yes history -d%ram%警his干-fb -g -ko -r崎L>nul
goto end
: overf1oll'
echo "G*** Environment Overfloll'本***
:end
if exist %ram%¥%fil%'.bat del %ra田耳干%fil%'..bat >nul
if exist %ram%¥*. $$$ del %ram見守*“$$$>nul
for耳%p in (fil hisl do set %%p=