入手先
開発環境
- Windows XP Pro SP3 32bit
- cmd.exe
- CScript/WScript
- VBScript 5.8
使い方
ディレクトリ名がC++Dir
など不正値ならエラーが出る。
半角英数字と.
,-
,_
の文字だけなら成功。
ダイアログは表示しない。
調査ログ
以下は読む必要なし。いろいろ大変だったログ。
バッチファイルで正規表現…はできなかった
http://oshiete.goo.ne.jp/qa/8335749.html
どうやらWindowsのコンソールcmd.exeでは、findstrコマンドを使うらしい。 でも、対象文字列をファイルから取得することしかできないっぽい。 コンソールの標準出力を対象にしたいのだが。
どうやらbat(cmd.exe)では、標準出力の文字列を正規表現チェックすることはできないらしい。
CScriptなら正規表現を扱える
http://kunst1080.hatenablog.com/entry/2013/06/23/235300
代わりにCScript(WScript)を使う。これもcmd.exe同様Windows限定。
https://msdn.microsoft.com/ja-jp/library/cc427970.aspx JScriptとVBScriptにおける正規表現の定義の仕方。違いがあるらしい。
リポジトリ名のチェックはCScript(vbs,js)でやろう。
batからvbsを呼び出す
set script_file=check.vbs
::set script_file=check.js
set script_param=
>call cscript //NoLogo "%script_file%" "%script_param%"
vbsからbatへ戻り値を返せない
ところで、戻り値は?見つけられなかった。
.batから.js(.vbs)を呼び出して、.batへ値を返したい。でも多分できない。
以下のような方法はあるらしいが、苦肉の策。 http://piyopiyocs.blog115.fc2.com/blog-entry-892.html http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q13151834463
スクリプト環境間でのやりとりは面倒すぎる
言語 | 戻り値 |
---|---|
.sh | 0~255(8bit値) |
.bat | たぶんshと同様。 |
cscript,wscript (.vbs,.js) | 見つけられなかった |
- 戻り値をやりとりする方法
- 環境変数を設定する(.bat, .sh)
- 異なるファイル間の場合も使えるのか。スコープが不明
- 一時ファイル
- ファイル書込、読取が必要。絶対嫌。
- 環境変数を設定する(.bat, .sh)
.sh, .batは環境変数を通じて渡すのが無難か。 ファイルをまたいだ環境変数のスコープについて調査する必要がありそう。 cscript(.vbs,.js)との連携は難しいか。 実行環境や言語が異なると、その連携で悩まされる。
方針
楽をするため、bat,sh,vbsの各スクリプト環境間での連携は考えないようにする。
VBS(JScript)で親ディレクトリ名が ^[0-9a-zA-Z._-]+$
のパターンに一致しているか確認しよう。
エラーならエラーダイアログを出せばいい。
もしエラーでないなら、JScript側から.batを呼び出せばいい。
気に食わない
しかし、Startするバッチが変わってしまう。 正規表現を使いたいため"だけ"にCScript(vbs,js)を使うのが気に食わない。 さらに、その制約のせいで開始バッチまで変わってしまう。
嫌だけど妥協するか。
頼れぬ.NET Framework
もしくはPowerShellを検討してみるか。
たかが正規表現のためだけに.NET Frameworkに依存するのが気に食わない。 curlの代わりになることができるならいいが、.NET 4.0のHttpRequestではGitHubと通信できなかった。
MSDN
https://msdn.microsoft.com/ja-jp/library/cc392403.aspx
Matchesのメンバについて説明がない。countがあるのかないのか。 http://www2s.biglobe.ne.jp/iryo/vba/part5/vbs2.html "Count"プロパティがあるらしい。
リファレンスなどの資料がしょぼい。 MSDNより個人サイトのほうで見つけたものもあった。
VBSは外部ファイルから呼び出せない
なんと、VBSは外部ファイルから呼び出せないらしい。 http://qiita.com/honeniq/items/88462b12d2244480026a VBSにはbatにおけるcallやstartに該当するものすらない。 関数をライブラリ化したかったのにできない。
かさばるコード
' ------------------
' 正規表現に一致するか
' ------------------
Function IsMutchRegExp(pattern, target)
Dim reg, Match, Matches, RetStr
Set reg = new RegExp
reg.Pattern = pattern
reg.IgnoreCase = False
reg.Global = True
Set Matches = reg.Execute(target)
If Matches.Count = 1 Then
IsMutchRegExp = True
Else
IsMutchRegExp = False
End If
End Function
' 親フォルダの名前を取得する
Dim fsobj, DirectoryName
Set fsobj = CreateObject("Scripting.FileSystemObject")
DirectoryName = fsobj.GetFolder(fsobj.GetParentFolderName(WScript.ScriptFullName)).Name
この程度の仕事をするのに、自前でこれだけコーディングが必要だった。 しかも本番はまだ。こいつらを利用して条件分岐やらが必要。
構文や記述もやたらと野暮ったくて面倒くさい。
まったく捗らない
実行環境に振り回される
たかがWebAPIで自動化したいだけなのに、.sh, .bat, .vbsの言語をさわる羽目になった。
文字コード問題(CP932/UTF8)、ファイルシステム間問題(区切文字などパス関係)、など、言語以前の問題に悩まされる。
さらに各言語の構文を知らねばならない。 変数の宣言や定義や使い方だけでも細かな違いがあって大変だった。
言語間、ファイル間で引数として簡単にやりとりできればよかったのだが、簡単にはできない。 文字コード問題、ファイルシステム間問題、そもそもインクルードできないなど。
おかげで、「親ディレクトリ名を取得する」ということを3言語で調査する羽目になった。 本当は、どこか1つだけで取得して、あとはパラメータとして渡したかった。 そうすれば私の学習も少しで済んだし、バッチ処理で同じことを何回もやらずに済む。
.bat
for %%I in (.) do set REPOSITORY_NAME=%%~nI%%~xI
.sh
REPO_NAME=`dirname "$0"`
REPO_NAME=`basename ${REPO_NAME}`
.vba
Dim fsobj, DirectoryName
Set fsobj = CreateObject("Scripting.FileSystemObject")
DirectoryName = fsobj.GetFolder(fsobj.GetParentFolderName(WScript.ScriptFullName)).Name
.shが最も分かりやすい。.bat, .vbaはどちらも分かりにくい。
もっと楽な方法はないのか
VBSを触った印象は最悪。 もはや問題をリストアップすることすら馬鹿馬鹿しいほど。 できれば二度と触りたくない。
こんなことならPythonやRubyのほうがまだ楽だったに違いない。 触ったことないけど。
いまさらだが、PythonやRubyならcurl的なことができるかもしれない。 そうすれば全部その言語だけで完結できる。 http://qiita.com/wappy100/items/4ee5ffa86e3cb9a3d970 http://techhey.hatenablog.com/entry/2014/01/24/015147
C#でできたら一番良かったのに…。 以前試したらできなかった。
WindowsXPという古い環境で、GitHubは通信プロトコルのバージョンが古いのが原因だった。 PythonやRubyでも同じ問題にぶちあたるかもしれない。 XPでは古いのしか使えないから。
所感
たかがディレクトリ名のバリデートごときでこれほど苦労するとは思わなかった。
きっともっと楽な方法はあるはず。