1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

コマンドライン引数でメタ文字を扱うとき

Posted at

ほんとうに初歩的なんですが、見事にハマったので戒めのために記事にします。

安全のために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);
    }
}

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?