etc

[쉘 스크립트] 변수, 조건문, 배포 자동화 스크립트

menuhwang 2022. 11. 15. 17:59

쉘 스크립트

개요

ec2에 연습 프로젝트를 배포하고 있다. 연습용 프로젝트이다보니 기능하나하나를 구현할때마다 배포하다보니 이 과정이 꽤나 번거로웠다.

  1. 도커 컨테이너 중지
  2. 도커 컨테이너 삭제
  3. 도커 이미지 삭제
  4. 깃 pull
  5. 도커 이미지 빌드
    1. gradle 빌드
  6. 컨테이너 실행

위 과정을 스크립트로 한 번에 동작할 수 있도록 자동화 해보면 좋겠다는 생각이 들어 쉘 스크립트를 짰고 쉘 스크립트를 짜면서 처음 접해본 내용을 정리해 보았다.

 

파라미터 입력

컨테이너 실행시 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