본문 바로가기

Rust

[Rust] Clap과 커맨드 라인 argument 다루기

반응형

 

Rust에서 command line을 다루는 법은 기본적으로 std::env::args가 있습니다. Clap은 Rust에서 커맨드 라인 인터페이스를 쉽게 만들 수 있도록 도와주는 크레이트입니다. 다양한 옵션과 설정을 통해 복잡한 커맨드 라인 애플리케이션도 쉽게 구축할 수 있습니다.

std::env::args 사용 예제

먼저 기본적으로 내장되어 있는 std::env::args를 사용한 예제를 알아봅니다.

예제 1

Command 라인 인자를 하나씩 처리합니다.

use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() > 1 {
        if args[1] == "-c" || args[1] == "--config" {
            if args.len() > 2 {
                println!("Value for config: {}", args[2]);
            } else {
                println!("No value for config");
            }
        }
    }
}
 

std::env::args는 뭔가 args, argc로 처리하는 C-style의 argement처리기입니다. iterator도 반환을 하기때문에 하나씩 인자를 받아서 처리하던가 해야합니다. 그리고 날것 그대로이기때문에 인자들이 제대로 들어왔는지 별도의 검사를 해야합니다.

예제 2

use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();

    println!("{:?}", args); // 통으로 표현 
    for (index, arg) in args.iter().enumerate() { // iterate
        println!("Argument {}: {}", index, arg);
    }
}

/*
$ ./target/debug/helloworld -c hello world
["./target/debug/helloworld", "-c", "hello", "world"]
Argument 0: ./target/debug/helloworld
Argument 1: -c
Argument 2: hello
Argument 3: world
*/

clap 설치

이번에는 좀더 나이스한 방법으로 argument를 처리하는 크레이트인 clap을 이용한 방법을 알아보도록 합니다.

Cargo.toml 파일에 다음과 같이 추가합니다.

[dependencies] 
clap = "2.33.3"

 

기본 사용법

clap의 기본적인 사용법들은 다음과 같습니다.

함수/메서드설명예제

App::new 새로운 App 인스턴스를 생성합니다. App::new("myapp")
App::version 앱의 버전을 설정합니다. .version("1.0")
App::author 앱의 저자를 설정합니다. .author("John Doe")
App::about 앱에 대한 설명을 설정합니다. .about("Does awesome things")
Arg::with_name 새로운 Arg 인스턴스를 생성합니다. Arg::with_name("config")
Arg::short 단축 옵션 문자를 설정합니다. .short("c")
Arg::long 긴 옵션 문자열을 설정합니다. .long("config")
Arg::takes_value 이 옵션이 값을 받아야 하는지 설정합니다. .takes_value(true)
Arg::required 이 옵션이 필수인지 설정합니다. .required(true)

예제

다음은 crate를 사용한 예제입니다.

 
extern crate clap;
use clap::{Arg, App};

fn main() {
    // version, author등은 help명령어로 확인가능하다
    let matches = App::new("MyApp")
                          .version("1.0")   
                          .author("Jack Doit")
                          .about("Beautiful awesome things")
                          .arg(Arg::with_name("config")
                               .short("c")
                               .long("config")
                               .value_name("FILE")
                               .help("Sets a custom config file")
                               .takes_value(true))
                          .get_matches();

    // config 값이 전달되었는지 확인
    if let Some(c) = matches.value_of("config") {
        println!("Value for config: {}", c);
    }
}

/*
>> ./helloword -h
MyApp 1.0
John Doe
Does awesome things

USAGE:
    helloworld [OPTIONS]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -c, --config <FILE>    Sets a custom config file

>> ./helloword -V
MyApp 1.0

값을 뭔가 체이닝을 통해서 인가를 합니다. 이 예제에서는 "MyApp"이라는 이름의 애플리케이션을 생성하고, 버전, 저자, 설명을 설정합니다. 그리고 "config"라는 이름의 인자를 설정하고, 이 인자가 단축 옵션 -c와 긴 옵션 --config을 가지며 값을 받을 수 있도록 설정합니다.

이 프로그램을 -c somefile 또는 --config somefile와 같이 실행하면, "Value for config: somefile"이 출력됩니다.

clap과 std::env::args 비교

clap과 std::env::args 둘 다 Rust에서 커맨드 라인 인자를 처리하는 방법을 제공하지만, 사용성과 기능성에서 차이가 있습니다.

테이블

기준 clapstd::env::args

복잡성 높음 (다양한 기능과 옵션) 낮음 (기본적인 문자열 처리만 가능)
유연성 매우 유연함 (다양한 옵션과 플래그 지원) 제한적 (수동으로 파싱해야 함)
에러 메시지 자동으로 생성 (옵션에 따라 커스터마이징 가능) 수동으로 처리해야 함
서브커맨드 지원 있음 없음 (수동으로 구현해야 함)
유효성 검사 내장된 유효성 검사 기능 있음 없음 (수동으로 구현해야 함)
문서 생성 자동으로 --help  --version 등을 생성 수동으로 구현해야 함
타입 안전성 강력한 타입 검사 타입 검사 없음
필수/옵션 인자 처리 내장된 기능으로 쉽게 처리 수동으로 처리해야 함
 
결론

clap은 복잡한 커맨드 라인 인터페이스를 쉽게 만들 수 있게 해주지만, 간단한 인자 처리만 필요한 경우에는 std::env::args가 더 적합할 수 있습니다.

반응형

'Rust' 카테고리의 다른 글

[Rust] Option<T> 의 사용방법에 대하여  (2) 2023.12.06
Rust in Jupyter notebook  (0) 2023.12.04
[Rust] Cargo 간단한 사용법  (0) 2023.09.05
[RUST] xlsxwriter  (0) 2023.07.24
[Rust] 제어문 If-else, while, do-while  (0) 2022.10.18