[Ubuntu] 셸 스크립트 프로그래밍
리눅스에서 Shell은 사용자와 운영체제간의 상호작용을 중개하는 인터페이스로 사용자의 명령을 해석하고 명령에 따라 시스템을 제어한다.
우분투에서는 bash 라는 셸을 사용한다.
셸 스크립트 프로그래밍은 C언어와 유사한 점이 많다.
변수 / 반복문 / 제어문 등을 사용할 수 있고, 컴파일 하지 않고 바로 텍스트 파일 형태로 실행할 수 있다.
셸 스크립트에서 변수는 사용 전 미리 선언할 필요가 없고, 값을 할당함과 동시에 변수가 생성된다.
모든 변수는 문자열로 취급되며 대입 시 좌우 공백이 없어야 한다.
셸은 여러 환경 변수 값을 가지는데, echo $환경변수명 명령어로 특정 환경변수에 접근할 수 있다.
나머지 반복문, 변수 사용, 제어문 등은 일반 프로그래밍 언어와 비슷하니 필요할 때 찾아서 사용하자.
셸 스크립트의 본질은 자동화이다.
배포, 리눅스 환경에서 사용자 등록, 파일 마운트 등의 작업을 수행 할 때는 명령어를 여러 차례 입력해야 하는데, 셸 스크립트를 사용하면 이 명령어들을 .sh 파일에 묶어놓고 한 번에 실행할 수 있다.
#!/bin/bash
# 이미지 이름 및 태그 설정
IMAGE_NAME="my_app_image"
TAG="latest"
# 이전 컨테이너 중지 및 삭제
docker stop my_app_container
docker rm my_app_container
# Dockerfile이 있는 디렉토리로 이동
cd /path/to/your/app
# 이미지 빌드
docker build -t $IMAGE_NAME:$TAG .
# 새로운 컨테이너 실행
docker run -d --name my_app_container -p 80:80 $IMAGE_NAME:$TAG
도커를 통해 애플리케이션을 배포하는 예시이다.
첫 줄에는 해당 소스코드가 셸로 작성됐음을 명시한다.
한 줄 씩 실행해야 됐던 배포 명령어를 .sh로 묶어서 처리한다.
chmod +x deploy.sh 명령어로 해당 셸 파일에 실행 권한을 부여하고, ./deploy.sh 명령어로 셸 스크립트를 실행한다.
#!/bin/bash
# 마운트 포인트 설정
MOUNT_POINT="/mnt/mydisk"
# 디스크 장치 설정
DISK_DEVICE="/dev/sdb1"
# 마운트 포인트 디렉토리가 없으면 생성
if [ ! -d $MOUNT_POINT ]; then
mkdir -p $MOUNT_POINT
fi
# 디스크 마운트
mount $DISK_DEVICE $MOUNT_POINT
# 성공적으로 마운트되었는지 확인
if [ $? -eq 0 ]; then
echo "Disk successfully mounted!"
else
echo "Error mounting the disk!"
fi
리눅스 환경에서 특정 디스크를 마운트하는 작업을 셸 스크립트로 자동화하는 예시이다.
변수와 제어문을 사용해 제대로 마운트됐는지 확인할 수 있다.
export PRJCT_ROOT=${ROOT-../../../contents}
# If there's a prestart.sh script in the /app directory or other path specified, run it before starting
#PRE_START_PATH=${PRE_START_PATH:-/app/prestart.sh}
echo "Checking for script in $PRE_START_PATH"
if [ -f $PRE_START_PATH ] ; then
echo "Running script $PRE_START_PATH"
. "$PRE_START_PATH"
else
echo "There is no script $PRE_START_PATH"
fi
# FastAPI
export APP_MODULE=${APP_MODULE-app.main:app}
export HOST=${HOST:-0.0.0.0}
export PORT=${PORT:-8001}
export SSH_PORT=${SSH_PORT:-22}
# run uvicorn for local test
exec uvicorn --reload --host $HOST --port $PORT \
--ssl-keyfile=$PRJCT_ROOT/cert/key.pem --ssl-certfile=$PRJCT_ROOT/cert/cert.pem \
--workers 4 --ws-ping-interval 30000 --ws-ping-timeout 30000 "$APP_MODULE"
poetry로 FastAPI로 작성한 애플리케이션을 실행하는 셸 스크립트이다.
export는 환경 변수를 설정하거나 이미 설정된 환경 변수의 값을 변경할 때 사용한다.
설정된 환경 변수는 해당 셸에서 시작한 모든 자식 프로세스들에게 상속된다.
${} 는 변수의 값을 참조할 때 사용된다.
export로 환경 변수를 설정한다. (변수가 정의되지 않았다면 기본 값을 사용한다)
exec 명령어는 실행된 프로그램을 현재 셸 프로세스를 환전히 대체한다.
exec으로 실행된 프로그램은 종료된 후 원래의 셸로 돌아오지 않고 셸 프로세스를 종료한다.
exec 뒤의 명령어는 uvicorn 서버를 시작하는 명령어로 FastAPI 애플리케이션을 배포할 때 사용된다.
--reload : 코드 변경 시 자동으로 서버를 다시 시작한다. (개발 시 사용)
--host $HOST : 서버가 바인딩할 호스트 주소를 설정한다.
--port $PORT : 서버가 바인딩할 포트를 설정한다.
--ssl-keyfile : https를 사용하기 위한 ssl 키 파일과 인증서 파일의 경로를 설정한다.
--workers 4 : 4개의 워커 프로세스를 사용해 서버를 실행한다. 멀티 프로세스 환경에서 서버의 처리 능력을 향상시킨다.
--ws-ping-interval 30000 : websocket 연결에 대한 timeout과 간격을 설정한다.
$APP_MODULE : FastAPI 애플리케이션의 위치를 나타낸다. 보통 app패키지의 main 모듈을 의미한다.
이렇듯 셸 스크립트는 .sh 파일으로 묶이고 리눅스 환경에서 자동화된 작업을 수행할 수 있도록 도와준다.
배포 자동화, 서비스 관리, 서버 설정 등 리눅스를 다룰 때 유용하게 사용하자.