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
내부로 진입해 남은 파라미터를 처리한다.