이 글에서는 Python을 사용하여 명령줄 인터페이스(Command Line Interface, CLI)를 개발하는 방법을 단계별로 살펴보겠습니다. 본격적인 코드 구현에 앞서, 먼저 명령줄이 무엇인지 간단히 짚고 넘어가겠습니다.
명령줄(Command Line)이란?
명령줄은 컴퓨터 프로그램의 역사와 함께해 온 가장 오래된 인터페이스 방식으로, 명령어를 기반으로 동작합니다. 명령줄 프로그램이란 셸(shell)이나 명령줄 환경에서 실행되는 프로그램을 의미합니다.
명령줄 인터페이스는 마우스 대신 터미널, 셸 또는 콘솔에 직접 명령어를 입력하여 조작하는 사용자 인터페이스를 제공합니다. GUI와 달리 텍스트 기반으로 동작하기 때문에 자동화 및 배치 작업에 특히 유용합니다.
CLI의 핵심 요소 3가지
명령줄 인터페이스는 하나의 실행 파일에서 시작되며, 프로그램의 설계 방식에 따라 다양한 형태의 매개변수를 전달할 수 있습니다. 대표적인 요소는 다음과 같습니다.
1. 인수(Argument)
스크립트에 반드시 전달해야 하는 필수 매개변수입니다. 인수가 누락되면 CLI는 오류를 발생시킵니다. 예를 들어 아래 명령에서 numpy가 인수에 해당합니다.
pip install numpy
2. 옵션(Option)
이름과 값의 쌍으로 구성된 선택적 매개변수입니다. 아래 명령에서 --cache-dir은 옵션이며, 값 ./my-cache-dir은 캐시 디렉터리 경로로 사용됩니다.
pip install django --cache-dir ./my-cache-dir
3. 플래그(Flag)
특정 동작을 활성화하거나 비활성화하도록 지시하는 선택적 매개변수입니다. 값을 따로 받지 않고 존재 여부만으로 의미를 가지며, 대표적인 예가 --help입니다.
Python CLI 개발 도구: click 패키지
Python은 'click'을 비롯한 여러 패키지를 통해 명령줄 인터페이스 작성을 손쉽게 지원합니다. 특히 click은 소량의 코드만으로 견고한 CLI를 구축할 수 있게 해주며, "DRY(Don't Repeat Yourself)" 원칙, 즉 코드 중복을 피하는 원칙을 자연스럽게 따르도록 설계되어 있습니다.
먼저 click 없이 작성한 CLI 프로그램부터 살펴보겠습니다. click을 사용한 버전과 비교하면 코드가 얼마나 장황한지 바로 확인할 수 있습니다.
click 없이 구현한 CLI 프로그램
import sys
import random
def do_work():
"""명령줄 사용을 처리하는 함수"""
args = sys.argv
args = args[1:] # args의 첫 번째 요소는 파일 이름이므로 제외
if len(args) == 0:
print('You have not passed any commands in!')
else:
for a in args:
if a == '--help':
print('Basic command line program')
print('Options:')
print(' --help -> show this basic help menu.')
print(' --monty -> show a Monty Python quote.')
print(' --veg -> show a random vegetable')
elif a == '--monty':
print("He's not the Messiah—he's a very naughty boy")
elif a == '--veg':
print(random.choice(['Tomato', 'Reddis', 'Carrot', 'Potato', 'Turnip']))
else:
print('Unrecognised argument.')
if __name__ == '__main__':
do_work()
실행 결과
c:\Python\Python361>python cli_interp1.py --monty He's not the Messiah—he's a very naughty boy c:\Python\Python361>python cli_interp1.py --help Basic command line program Options: --help -> show this basic help menu. --monty -> show a Monty Python quote. --veg -> show a random vegetable c:\Python\Python361>python cli_interp1.py --veg Tomato c:\Python\Python361>python cli_interp1.py --error Unrecognised argument.
위 코드에서 알 수 있듯이, sys.argv를 직접 파싱하는 방식은 인수 이름을 변경하거나 새 옵션을 추가할 때 유연성이 크게 떨어집니다. 도움말 메뉴조차 일일이 문자열로 작성해 주어야 하기 때문입니다.
click 패키지를 사용한 CLI 프로그램
이번에는 동일한 기능을 click 패키지로 구현해 보겠습니다.
import click
import random
@click.command()
@click.option('--monty', default=False, help='Show a Monty Python quote.')
@click.option('--veg', default=False, help='Show a random vegetable.')
def do_work(monty, veg):
"""Basic Click example will follow your commands"""
if monty:
print("He's not the Messiah—he's a very naughty boy")
if veg:
print(random.choice(['Tomato', 'Reddis', 'Carrot', 'Potato', 'Turnip']))
if __name__ == '__main__':
do_work()
실행 결과
c:\Python\Python361>python cli_interp2.py --help Usage: cli_interp2.py [OPTIONS] Basic Click example will follow your commands Options: --monty TEXT Show a Monty Python quote. --veg TEXT Show a random vegetable. --help Show this message and exit.
결과에서 확인할 수 있듯이, click 패키지를 사용하면 --help 옵션까지 자동으로 생성됩니다. 데코레이터 몇 줄만으로 옵션 정의, 기본값 설정, 도움말 문구 관리가 모두 처리되므로 코드가 훨씬 간결해지고 유지보수도 쉬워집니다. 이처럼 click을 활용하면 개발 시간과 노력을 크게 절약할 수 있어, 실무에서 Python CLI를 개발할 때 가장 널리 권장되는 방식 중 하나입니다.