ほんとうに初歩的なんですが、見事にハマったので戒めのために記事にします。
安全のためにCLIの引数ではメタ文字をエスケープ処理するのは当たり前なんですが、Printデバッグなんてしていると"\n"が標準出力では"\n"になるため内部でエスケープされていることを見落とすことがあります。
(そもそも標準出力にメタ文字がある時点でエスケープ処理されていることに気づけよ…)
たまにエスケープを破壊したくなるときがあるのですが、そういうとき私はエスケープ破壊の関数で任意のメタ文字だけ置換して処理しています。
下記はRustで引数を文字列とバイト列で表示するサンプルコードです。
コマンドラインパーサにはclap("2.20.3")を利用しています。
ビルドした実行ファイルに引数として"hoge\nhuga"を渡すとエスケープされているのがわかりやすいと思います。
./main.rs
# [macro_use]
extern crate clap;
use clap::{Arg};
fn run(message: &str){
let t = "hoge\nhuga";
let tb = t.as_bytes();
let mut mb = message.as_bytes();
println!("literal<{}>:{:?}", t, &tb);
println!("clapString<{}>:{:?}", message, &mb);
//エスケープ破壊の関数で対処
println!("unescape:{}", unescape(&message));
}
fn unescape(message: &str) -> String{
let rs = message
.replace("\\n", "\n");
rs
}
fn main() {
let _args = app_from_crate!()
.arg(Arg::with_name("message")
.help("send Message.")
.required(true)
)
.get_matches();
if let Some(o) = _args.value_of("message"){
println!("input value: {}", o);
run(o);
}
}