CONTAINER技術系のこと書きます。記述している技術書に記載するコマンドライン操作がちゃんと動くか確認する方法について考えてみた話。このエントリでは、コマンドライン操作を記述しているテキストファイルをシェルスクリプトに変換して実行する方法を提案する。慣れていないので、もっと良いやり方があれば教えてもらいたい。使った環境は次の通り。コマンドライン操作を記載する方法についてプロプロセッサ命令を使って外部のファイルを取り込むプロプロセッサ命令を使って外部のファイルの一部を取り込むプリプロセッサ命令を頼りに外部のファイルをシェルスクリプトに変換する技術書にコマンドライン操作を記載する際の課題について技術書にコマンドライン操作を記載する場合、その内容が実機でちゃんと動作するか確認する必要がある。それも、動作確認は一回やって終わりではなく、少なくとも書籍が完成するまでは継続的に実施することになる。記載する内容は随時修正される可能性があるから。ある箇所を修正したら、別の箇所で整合性が取れなくなっていないかレグレッションテストしなければならない。出版してからも、使っているシステムやツールの更新などによって動作しなくなっていないか確認することが望ましい。上記の作業を手作業で実施することには困難が伴う。内容を修正する度に、本から一行ずつコマンドをコピペしていく作業は考えただけで気が遠くなる。そのため、なるべく一連の作業は自動化することが望ましい。コマンドライン操作特有の要件として、以下のようなものがある。おいて自動化する方法を考えてみた。具体的には、一連のコマンドライン操作をプリプロセッサが解釈する命令を頼りにシェルスクリプトに変換する。シェルスクリプトの形になっていれば、実機で実行することも比較的容易といえるはず。使って課題を解決するまでの流れを解説する。環境構築などについては以下のエントリを参照のこと。blog.amedama.jpまずはサンプルとなるプロジェクトを用意しよう。プロジェクトを作成する。example-bookすると、次のように必要なファイル一式が用意される。ファイルがデフォルトで組み込まれるマークアップテキストファイルとなる。命令を使っていくつかのコマンドライン操作を示すように、マークアップテキストファイルを編集している。ms//}EOF-それでは、実際に上記をテキストフォーマットにビルドしてみよう。textビルドすると、次のような結果が得られた。コマンドラインの操作が本の中に組み込まれていることがわかる。ms◆→終了:コマンド←◆プロプロセッサ命令を使って外部のファイルを取り込む先ほどのやり方では、コマンドライン操作を直接マークアップテキストファイルに記述した。このやり方は単純で分かりやすい反面、記述した内容を変更する際のメンテナンス性が悪い。プリプロセッサを使ってファイルのファイルに記述された内容を取り込むことができる。いう名前でコマンドライン操作を記述したテキストファイルを用意する。読み込むように指定する。preprocすると、プリプロセッサ命令の中にファイルの内容が取り込まれる。ms#@end//}もちろん、ビルドした後の成果物にはプリプロセッサ命令は残らない。ms◆→終了:コマンド←◆プロプロセッサ命令を使って外部のファイルの一部を取り込む先ほどのやり方も、直接マークアップテキストファイルにコマンドライン操作をベタ書きするよりはだいぶメンテナンス性がよくなる。本の中で取り扱うコマンドライン操作が多いと、大量のファイルを扱うことになってこれまたメンテナンス性が悪い。ファイルの一部だけを取り込むプリプロセッサ命令も用意されている。それぞれのコマンドライン操作をプリプロセッサ命令を使って別々に取り出すことを考えてみよう。この場合、次のように外部のファイルにもプリプロセッサ命令を記述する。使って取り出す範囲を指定する。ms#@range_end(ping)#@range_end(whole)EOF-コマンドライン操作を記述したファイルが用意できたら、それをマークアップテキストファイルに取り込む。使って取り出す内容を指定する。World//cmd{#@maprange(commands.txt,echo)#@end//}//cmd{#@maprange(commands.txt,cat)#@end//}//cmd{#@maprange(commands.txt,ping)#@end//}//cmd{#@maprange(commands.txt,whole)#@end//}EOFプリプロセスを実行する。preprocすると、次のようにファイルの一部分が取り込まれる。ms#@end//}ビルドした結果は次の通り。ms◆→終了:コマンド←◆プリプロセッサ命令を頼りに外部のファイルをシェルスクリプトに変換するさて、これでようやく前提知識の共有が終わったので本題に入る。基本的なコンセプトとしては、コマンドライン操作を記述したファイルの内容をシェルスクリプトに変換したい。シェルスクリプトに変換できれば、あとはそれを実機上で実行するだけで済む。コマンドライン操作を記述したファイルはそのままだと使えない。出力の内容も含まれている。ヒアドキュメントや複数行のコマンドライン操作も存在して話をややこしくしている。そこで、実際には使わないプリプロセッサ命令を使って「ここがコマンドラインで実行したい箇所ですよ」と印をつけることにした。論よりソースということで、以下のコマンドで生成されるファイルを見てほしい。使って、実際に実行したいコマンドライン操作の前後にプリプロセッサ命令が記述されている。ms#@range_end(ping)#@range_end(whole)EOF-上記のように、実際には使われないプリプロセッサ命令が含まれていたとしても、無視されるだけで成果物のビルドには影響を与えない。ms◆→終了:コマンド←◆しかし、命令を頼りにコマンドライン操作で実行したい箇所を次のように取り出すことはできる。使ってシェルスクリプトに変換してみた。いえ、別に何を使っても良いと思う。sed=gsedこんな感じでシェルスクリプトに変換できる。返ったときに止まるので異常に気づきやすくなる。8.8.8.8変換したスクリプトを、ファイルとして書き出してみよう。commands.shできたシェルスクリプトを実行してみる。msちゃんと実行できた。しているので、リダイレクトでファイルが上書きできないようにしてある。一度実行してみたときコマンドライン操作の中でファイルを上書きしてしまっているということにも気づける。ms#@range_end(ping)#@range_end(whole)EOF-シェルスクリプトを作り直す。commands.sh実行すると、今度は失敗しない。スクリプトに冪等性が得られた。msこのやり方ならコマンドラインの操作とテストする内容が二重管理にもならないところが良いかなーと思っている。コマンドライン操作を記述するファイルがちょっとごちゃごちゃするね。あと、解決できていない課題もある。ユーザの入力を伴うインタラクティブな操作があるときどうするかとか。あと、複数のターミナルにまたがった操作をどうするか、とか。未処理の例外が上がったときの処理をオーバーライドする注目記事スポンサードリンクスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。