서론
Go 언어는 간단하게 CLI(Command-Line Interface) 프로그램을 작성할 수 있는 표준 패키지를 제공한다. 명령줄에서 데이터를 입력받아 처리하거나 옵션을 지정하는 방식은 많은 개발자들에게 익숙한 방법이다. flag 패키지를 사용하면 명령줄 옵션을 간단하게 정의하고 파싱할 수 있으며, 기본값 설정과 도움말 출력 같은 기능까지 손쉽게 구현할 수 있다. 이번 글에서는 flag 패키지의 간단한 사용법을 CLI 프로그램 예제를 통해 소개한다.
명령줄 옵션 정의
v := flag.Bool("v", false, "show version info")
name := flag.String("name", "", "Your name")
sleep := flag.Int("sleep", 1, "Sleep second")
명령줄 옵션은 각 옵션의 타입에 맞는 flag 패키지의 메소드를 사용하여 정의할 수 있다. 이 메소드에는 옵션 이름, 기본값, 옵션 설명을 인수로 전달하면 해당하는 타입에 맞는 포인터 변수가 반환된다. 반환된 포인터 변수는 기본값이 저장되어 있으며 nil이 반환되지 않기 때문에 별도의 검사 없이 안전하게 사용할 수 있다.
명령줄 옵션 파싱
flag.Parse()
명령줄 옵션을 정의한 후 flag.Parse()를 호출하면 입력된 명령줄 옵션을 파싱하고 정의된 변수에 해당 값을 자동으로 할당한다. 이 한 줄만으로 옵션 파싱이 간단하게 완료된다.
잠자기 프로그램
package main
import (
"flag"
"fmt"
"time"
)
func main() {
v := flag.Bool("v", false, "Show version info")
name := flag.String("name", "", "Your name")
sleep := flag.Int("sleep", 1, "Sleep second")
flag.Parse()
if *v {
fmt.Println("Jae-Sung example version 0.0.1")
return
}
fmt.Print("Hello")
if len(*name) > 0 {
fmt.Printf(", %s!\n", *name)
} else {
fmt.Println("!")
}
if *sleep > 0 {
fmt.Printf("%d Second SLEEP\n", *sleep)
time.Sleep(time.Duration(*sleep) * time.Second)
}
}
명령줄 옵션을 처리하는 간단한 예제 코드로 프로그램을 실행하면 인삿말을 출력되고 지정된 시간만큼 Sleep한 후 종료된다. -v 옵션을 사용하면 프로그램의 버전 정보를 출력하고 종료되며, -name 옵션을 사용하여 실행하면 인삿말에 사용자가 지정한 이름을 포함하여 출력한다. 기본적으로 1초 Sleep을 수행하지만 -sleep 옵션을 사용하면 원하는 시간을 초 단위로 지정할 수 있다.
실행 결과
$ ./sleep_example -v
Jae-Sung example version 0.0.1
$ ./sleep_example -name Jae-Sung
Hello, Jae-Sung!
1 Second SLEEP
$ ./sleep_example -name Jae-Sung -sleep 5
Hello, Jae-Sung!
5 Second SLEEP
도와줘요!
$ ./sleep_example -h
Usage of ./sleep_example:
-name string
Your name
-sleep int
Sleep second (default 1)
-v show version info
기본적으로 flag 패키지는 별다른 작업 없이 잘못된 옵션이 입력되었거나 -h 또는 -help 옵션이 사용된 경우 자동으로 명령줄 옵션에 대한 설명을 출력한다.
마무리
표준 패키지만으로도 간단한 명령줄 옵션을 구현할 수 있어 간단한 CLI 프로그램을 작성해야 할 때는 flag 패키지를 사용하면 충분하다. 그러나 더 고급 기능이나 복잡한 명령어 파싱이 필요하다면 cobra와 같은 외부 패키지를 활용할 수 있다. cobra는 더욱 풍부한 기능을 제공하지만 표준 패키지로 간단하게 해결할 수 있는 문제에는 flag 패키지가 충분히 적합하다.
'Language > Go' 카테고리의 다른 글
[golang] panic과 recover로 try-catch 따라 하기 (1) | 2024.11.21 |
---|---|
[golang] path/filepath 패키지로 멀티 플랫폼에서 파일 경로 처리 (1) | 2024.11.20 |
[golang] Go 언어 철학에서 switch문이 살아 남은 이유 (3) | 2024.11.18 |
[golang] runtime 패키지로 메모리 사용 추적 (0) | 2024.11.17 |
[golang] 메모리 지역성을 고려한 2차원 슬라이스 순회 (0) | 2024.11.16 |