C#でコマンド引数解析する
成果物
情報源
公式ライブラリにコマンド引数パーサは存在しない。そこで、NuGetを使って第三者が作成したライブラリを拝借する。いくつかあるが、最も簡単らしいCommandLineParserを使う。
インストール
CommandLineParserをインストールする。mono
, nuget.exe
がインストール済みであること。install.sh
mono $(which nuget.exe) install CommandLineParser
コード
class Options { [Option('a', "aaa", Required = false, HelpText = "ヘルプ用説明文。")] public string A { get; set; } = ""; }
public class Program { public static void Main(string[] args) { Parser.Default.ParseArguments<Options>(args) .WithParsed(opt => { Run(opt); }) .WithNotParsed(er => { Error(er); }); } private static void Run(Options opt) { Console.WriteLine("CommandLine parse success !!"); Console.WriteLine($"A: {opt.A}"); } private static void Error(IEnumerable<Error> er) { Console.WriteLine("CommandLine parse failed..."); foreach (Error e in er) { Console.WriteLine(e); } } }
ビルド
csc \ -nologo \ -recurse:*.cs \ -nullable:enable \ -langversion:latest \ -r:CommandLine.dll
実行
mono Program.exe -a ABC mono Program.exe --aaa ABC
CommandLine parse success !! A: ABC
所感
まあまあの使用感。
サブコマンドも1階層だけなら作れるらしい。でも、ジェネリクスが大変なことになる……。サブコマンドの数だけ増えていく。これはひどい。
Parser.Default.ParseArguments<MySubCommand1, MySubCommand2, MySubCommand3>(args) .WithParsed<MySubCommand1>(opt1 => { /**/ }) .WithParsed<MySubCommand2>(opt2 => { /**/ }) .WithParsed<MySubCommand3>(opt2 => { /**/ }) .WithNotParsed(er => { /**/ }) ;
あと、サブコマンドを省略したときはどうなるの? パース失敗じゃなくサブコマンド1を実行させたい。できるかな? 要検証。
対象環境
- Raspbierry pi 4 Model B
- Raspberry Pi OS buster 10.0 2020-08-20 ※
- bash 5.0.3(1)-release
- mono 6.12.0.90
- csc 3.6.0-4.20224.5 (ec77c100)
- msbuild 16.6.0.32601
- mono 5.18.0.240
- Eto.Forms 2.4.1 拡張機能, NuGetパッケージ
- nuget.exe 5.7.0.6726
- dotnet 3.1.100
$ uname -a Linux raspberrypi 5.4.72-v7l+ #1356 SMP Thu Oct 22 13:57:51 BST 2020 armv7l GNU/Linux