카테고리 없음

[Bash] Bash script로 Usage 만들기 1

mkdir 2021. 9. 12. 09:43

Bash shell

  • 초대 Unix shell인 Bournshell의 뒤를 잇는 친구
  • Ubuntu 및 CentOS 환경에서는 대부분 많이 쓰고 있는 듯 하다.(다른 OS는 건드려보지 못해서 모르겠다)
  • 대부분의 linux 배포에는 기본적으로 포함되어있지만, alpine의 경우에는 포함하고 있지 않다.

스크립트 작성

인터프리터 선언

#!/bin/bash
  • 쉬뱅(Shebang)이라 부르는, 파이썬으로 치면 source venv/bin/activate와 같이 이 파일을 실행할 인터프리터를 지정해준다. 외에도 /bin/sh. /bin/zsh등이 있지만 대부분 bash 혹은 sh를 사용한다.
  • 반드시 절대 경로로 설정해줘야 하며, 설정해주지 않을 경우 해당 OS의 기본 쉘을 사용하게 되지만, 어지간해서는 써주는 것을 강력히 추천한다.

Usage 함수 작성

function usage {
        echo "./test.sh USAGE"
        echo "-log PATH           path to logdir"
        echo "-v HOST:DEST      path to bind volume DEST"
        echo ""
}
  • 무식해 보이지만 이게 방법이다(...)
  • 저게 정 보기 싫다면 cat + EOF로 작성하는 방법이 있긴 하지만, 유서깊은 Usage 작성법을 따라가기로 하자.

분기 설정

if [ -z "$#" ] ; then
        usage
else
        ~
fi
  • 대부분 Bash script의 경우 그대로 실행해도 되는 것도 있지만 그대로 실행하지 않고 뭔가 파라미터를 받아서 처리하는 친구들도 있다.
  • 이 경우에는 파라미터를 반드시 파라미터를 받아 처리해야 하는 스크립트를 가정했다.
  • $#로 스크립트가 받는 파라미터 값을 전부 끌어온다. 파라미터가 없을 경우, usage를 출력하고 종료한다.
  • 받은 파라미터가 있을 경우 else문으로 분기한다.

파라미터 쉬프트

...
else
        while true ; do
                case $1 in
                        --log)
                                echo "====="
                                shift 1
                                echo "logdir=$1"
                                shift 1
                                echo "====="
                                ;;
                        -v)
                                echo "====="
                                shift 1
                                echo "volumes=$1"
                                shift 1
                                echo "====="
                                ;;
                        *)
                                echo "====="
                                shift 1
                                echo "some values"
                                shift 1
                                echo "====="
                                ;;
                esac
                if [ -z "$1" ] ; then
                        echo "exit zero code"
                        exit 0
                fi
        done
fi
  • 분기한 else문 내부에서, $#로 모조리 끌어온 파라미터들을 처리해야 한다. getopts가 아니라 $#로 파라미터를 가져오게 될 경우, 해당 파라미터 값들은 배열에 통째로 담아 끌어오기 때문에, 플래그와 파라미터를 구분할 필요가 있다.
  • $1으로 가장 앞에 있는 값을 가져오면, 해당 값은 --log, -v와 같은 플래그일 것이다. case ~ esac으로 가져온 플래그에 따라 분기하고, case로 분기한 내부에서 $1로 가져온 플래그를 shift로 제거한다.
  • 플래그가 shift에 따라 제거되면, 다음 $1의 값은 해당 플래그의 파라미터 값이므로, 해당 파라미터 값에 따른 처리를 해준다(예시에서는 단순한 echo만 주었다)
  • 이제 파라미터 값으로 처리가 끝났다면 해당 파라미터 값 역시 배열에서 제거해줘야 한다. 다시 shift로 파라미터를 제거해준다.
  • case 구분의 조건 처리가 모두 끝났으니 if ~ fi내부로 들어간다. -z "$1"로 남은 파라미터가 있는지 확인하고, 남은 파라미터가 없다면 종료코드 0으로 스크립트를 종료한다.
  • while의 반복 조건이 true이므로, 남은 스크립트가 있다면 다시 돌아 case내부로 진입해 남은 파라미터를 처리한다.