[쉘 스크립트] 변수, 조건문, 배포 자동화 스크립트
쉘 스크립트
개요
ec2에 연습 프로젝트를 배포하고 있다. 연습용 프로젝트이다보니 기능하나하나를 구현할때마다 배포하다보니 이 과정이 꽤나 번거로웠다.
- 도커 컨테이너 중지
- 도커 컨테이너 삭제
- 도커 이미지 삭제
- 깃 pull
- 도커 이미지 빌드
- gradle 빌드
- 컨테이너 실행
위 과정을 스크립트로 한 번에 동작할 수 있도록 자동화 해보면 좋겠다는 생각이 들어 쉘 스크립트를 짰고 쉘 스크립트를 짜면서 처음 접해본 내용을 정리해 보았다.
파라미터 입력
컨테이너 실행시 DB 연결 정보같은 민감한 정보를 환경변수로 전달해야한다.
쉘 스크립트에 그 부분이 함께 작성되어 깃허브에 올릴 수 없기때문에 스크립트 실행 단계에서 값을 입력 받고자 했다.
도커 컨테이너 실행 명령어
sudo docker run -d --name likelion-hospital -p 8080:8080 \\
-e SPRING_DATASOURCE_URL={spring.datasource.ur} \\
-e SPRING_DATASOURCE_USERNAME={spring.datasource.username} \\
-e SPRING_DATASOURCE_PASSWORD={spring.datasource.password} \\
likelion-hospital
파라미터 개수
$# : 입력된 파라미터 개수를 반환한다.
if [ $# > 3 ]; then
# ...
fi
입력된 파라미터의 개수로 정상적으로 필요한 파라미터 전부가 들어왔는지 확인했다.
파라미터
$1 $2 $n : 첫 번째 파라미터, 두 번째 파라미터, n번째 파라미터를 반환한다.
DATASOURCE_URL=$1
DATASOURCE_USERNAME=$2
DATASOURCE_PASSWORD=$3
첫 번째 파라미터는 db host 주소를, 두 번째 파라미터는 db username, 세 번째는 password를 입력받아 각 변수에 저장하도록 했다.
쉘 스크립트 실행 파라미터 전달
sudo sh release.sh {spring.datasource.url} {spring.datasource.username} {spring.datasource.password}
변수
선언 및 사용
NAME=likelion-hospital
PORT=8080
DATASOURCE_URL=$1
DATASOURCE_USERNAME=$2
DATASOURCE_PASSWORD=$3
컨테이너 이름, 이미지 이름, 컨테이너 포트 등을 다른 사용자가 쉽게 변경하고, 스크립트에서 재사용할때 편하도록 변수를 선언해주었다.
변수는 Key=Value 형식으로 선언해주면 되고 $변수명 으로 값을 가져와 사용 할 수 있다.
주의사항
변수 선언시 = 좌우에 띄어쓰기 하지 말것!
띄어쓰기가 있으면 인식하지 못함.
주의사항
docker run -d --name $NAME -p $PORT:8080 \\
-e SPRING_DATASOURCE_URL=$DATASOURCE_URL \\
-e SPRING_DATASOURCE_PASSWORD=$DATASOURCE_PASSWORD \\
-e SPRING_DATASOURCE_USERNAME=$DATASOURCE_USERNAME \\
$NAME
응용
변수에 컨테이너 아이디나 이미지 아이디를 검색해서 담고 싶었다. (docker rm $NAME docker rmi $NAME 으로 해도 되지만) 생성되어있는 컨테이너가 있는지 이미 같은 이름으로 빌드된 이미지가 있는지 확인할 수 있기 때문이었다.
CONTAINER=$(docker ps -aq --filter "name=$NAME")
IMAGE=$(docker images --filter=reference="$NAME" -q)
$() 안에 콘솔 명령어를 입력하면 반환된 값을 벨류로 설정할 수 있다.
조건문 if
비교 연산자
비교 연산자의 경우 정수 비교, 문자열 비교 방법이 다르다.
Bash Script에서 사용하는 비교 연산자 정리
Bash Script에서 자주 사용하는 비교 연산자 [ 정수 비교 ] 연산자 의미 표현 -eq (같음) if [ $a -eq $b...
blog.naver.com
CONTAINER 변수, IMAGE 변수가 있는지 없는 지에 따라 다른 동작을 하도록 하고 싶었다.
그래서 -n 연산자를 사용했다. -n 은 문자열의 길이가 0이 아니면 true 를 반환한다.
-z 도 있다. -z 는 문자열의 길이가 0이면 true를 반환한다.
if
if [ 조건식 ]; then
# 참일때 실행될 명령
else
# 거짓일때 실행될 명령
fi # 조건문 종료
주의사항
조건식과 [ ] 사이에 띄어쓰기를 반드시 넣어줘야한다!
CONTAINER 변수가 있으면 생성되어있는 컨테이너가 있다는 것이므로, 컨테이너를 종료하고 삭제한다.
IMAGE도 마찬가지로 존재 여부를 확인해서 이미지가 있으면 기존 이미지를 삭제한다.
if [ -n "$CONTAINER" ];
then
echo "컨테이너 종료"
docker stop $CONTAINER
echo "컨테이너 삭제"
docker rm $CONTAINER
fi
if [ -n "$IMAGE" ]; then
docker rmi $IMAGE
fi
결과
배포 자동화 스크립트
#!/bin/bash
NAME=likelion-hospital
PORT=8080
DATASOURCE_URL=$1
DATASOURCE_USERNAME=$2
DATASOURCE_PASSWORD=$3
if [ $# != 3 ];
then
echo "파라미터를 확인해주세요."
echo "DATASOURCE_URL:$1"
echo "DATASOURCE_USERNAME:$2"
echo "DATASOURCE_PASSWORD:$3"
exit
fi
CONTAINER=$(docker ps -aq --filter "name=$NAME")
if [ -n "$CONTAINER" ];
then
echo "컨테이너 종료"
docker stop $CONTAINER
echo "컨테이너 삭제"
docker rm $CONTAINER
fi
IMAGE=$(docker images --filter=reference="$NAME" -q)
if [ -n "$IMAGE" ]; then
docker rmi $IMAGE
fi
git pull
docker build -t $NAME .
docker run -d --name $NAME -p $PORT:8080 -e SPRING_DATASOURCE_URL=$DATASOURCE_URL -e SPRING_DATASOURCE_PASSWORD=$DATASOURCE_PASSWORD -e SPRING_DATASOURCE_USERNAME=$DATASOURCE_USERNAME $NAME