파일 복사 방식의 patch 스크립트

#!/bin/bash
###########################################################
#
# 특정 파일 또는 디렉토리를 덮어 쓰는 방식의
# 패치를 적용하기 위한 스크립트
#
###########################################################
LANG="ko_KR.UTF-8"
CURRENT_TIME=$(date "+%Y%m%d_%H%M%S")
CURRENT_DIR=$(pwd)
PATCH_FILES_DIR="patch_files"
TMP_FILE="/tmp/__tmp__.$$$"

PATCH_FILES=( \
"/opt/gate1/www/ONE_user/user_add.html" \
"/opt/gate1/www/include/function/user.fun" \
"/opt/gate1/www/ONE_device/device_process.php" \
"/opt/gate1/www/include/function/device.fun" \
)

###########################################################
# "엔터키 누르면 다음으로 이동" 메세지 표시
###########################################################
func_continue() {
  echo "###########################################################"
  echo "# Press ENTER to continue..."
  echo "###########################################################"
  read
}

###########################################################
# 파일이 존재하는지 검사한다.
# 파일이 없으면 스크립트를 종료한다.
###########################################################
func_prepare() {
  echo "###########################################################"
  echo "#"
  echo "# func_prepare"
  echo "#"
  echo "###########################################################"

  for TMPV in ${PATCH_FILES[@]}
  do
    if [ ! -f "${TMPV}" ]
    then
      echo "${TMPV} not found !"
      exit 1
    fi
  done
}

###########################################################
# 백업 디렉토리를 만들고 기존 파일을 백업한다.
# 이 함수는 반드시 패치를 적용하기 전에 호출되어야 한다.
###########################################################
func_backup() {
  echo "###########################################################"
  echo "#"
  echo "# func_backup"
  echo "#"
  echo "###########################################################"

  if [ ! -d "${CURRENT_DIR}/backup.${CURRENT_TIME}" ]
  then
    mkdir -p "${CURRENT_DIR}/backup.${CURRENT_TIME}"
  fi

  for TMPV in ${PATCH_FILES[@]}
  do
    FILE_PATH=$(dirname ${TMPV})
    FILE_NAME=$(basename ${TMPV})
    mkdir -p "${CURRENT_DIR}/backup.${CURRENT_TIME}${FILE_PATH}"
    cp -av ${TMPV} "${CURRENT_DIR}/backup.${CURRENT_TIME}${FILE_PATH}/"
  done
}

###########################################################
# 현재 서버가 개발 서버일 경우 기존 실행파일을 가지고
# 패치를 만든다.
# 파일은 ${PATCH_FILES_DIR} 안에 원본 디렉토리 구조로 들어간다.
###########################################################
func_make_patch() {
  echo "###########################################################"
  echo "#"
  echo "# func_make_patch"
  echo "#"
  echo "###########################################################"

  if [ ! -d "${CURRENT_DIR}/${PATCH_FILES_DIR}" ]
  then
    mkdir -p "${CURRENT_DIR}/${PATCH_FILES_DIR}"
  fi

  for TMPV in ${PATCH_FILES[@]}
  do
    FILE_PATH=$(dirname ${TMPV})
    FILE_NAME=$(basename ${TMPV})
    mkdir -p "${CURRENT_DIR}/${PATCH_FILES_DIR}${FILE_PATH}"
    cp -av ${TMPV} "${CURRENT_DIR}/${PATCH_FILES_DIR}${FILE_PATH}/"
  done
}

###########################################################
# 패치를 적용한다.
# (현재 디렉토리에 패치 파일들이 있음)
###########################################################
func_run_patch0() {
  echo "###########################################################"
  echo "#"
  echo "# func_run_patch0"
  echo "#"
  echo "###########################################################"

  # 패치 파일이 정상적으로 존재하는지 검사한다.
  for TMPV in ${PATCH_FILES[@]}
  do
    FILE_PATH=$(dirname ${TMPV})
    FILE_NAME=$(basename ${TMPV})
    if [ ! -f "${CURRENT_DIR}/${FILE_NAME}" ]
    then
      echo "${CURRENT_DIR}/${FILE_NAME} not found."
      exit 1
    fi
  done

  # 패치 실행
  for TMPV in ${PATCH_FILES[@]}
  do
    FILE_PATH=$(dirname ${TMPV})
    FILE_NAME=$(basename ${TMPV})
    if [ ! -d "${FILE_PATH}" ]
    then
      mkdir -p "${FILE_PATH}"
    fi
    cp -av "./${FILE_NAME}" "${FILE_PATH}/"
  done
}

###########################################################
# 패치를 적용한다.
# (${PATCH_FILES_DIR} 안에 패치 파일들이 있음)
###########################################################
func_run_patch1() {
  echo "###########################################################"
  echo "#"
  echo "# func_run_patch1"
  echo "#"
  echo "###########################################################"

  # 패치 파일이 정상적으로 존재하는지 검사한다.
  for TMPV in ${PATCH_FILES[@]}
  do
    FILE_PATH=$(dirname ${TMPV})
    FILE_NAME=$(basename ${TMPV})
    if [ ! -f "${CURRENT_DIR}/${PATCH_FILES_DIR}/${FILE_NAME}" ]
    then
      echo "${CURRENT_DIR}/${PATCH_FILES_DIR}/${FILE_NAME} not found."
      exit 1
    fi
  done

  # 패치 실행
  for TMPV in ${PATCH_FILES[@]}
  do
    FILE_PATH=$(dirname ${TMPV})
    FILE_NAME=$(basename ${TMPV})
    if [ ! -d "${FILE_PATH}" ]
    then
      mkdir -p "${FILE_PATH}"
    fi
    cp -av "${CURRENT_DIR}/${PATCH_FILES_DIR}/${FILE_NAME}" "${FILE_PATH}/"
  done
}

###########################################################
# 패치를 적용한다.
# (${PATCH_FILES_DIR} 안에 원본 디렉토리 구조로 패치
# 파일들이 있음)-func_make_patch 함수로 만든 패치
###########################################################
func_run_patch2() {
  echo "###########################################################"
  echo "#"
  echo "# func_run_patch2"
  echo "#"
  echo "###########################################################"

  # 패치 파일이 정상적으로 존재하는지 검사한다.
  for TMPV in ${PATCH_FILES[@]}
  do
    FILE_PATH=$(dirname ${TMPV})
    FILE_NAME=$(basename ${TMPV})
    if [ ! -f "${CURRENT_DIR}/${PATCH_FILES_DIR}${TMPV}" ]
    then
      echo "${CURRENT_DIR}/${PATCH_FILES_DIR}${TMPV} not found."
      exit 1
    fi
  done

  # 패치 실행
  find "${CURRENT_DIR}/${PATCH_FILES_DIR}" -type d -exec chmod 755 {} \;
  find "${CURRENT_DIR}/${PATCH_FILES_DIR}" -type f -exec chmod 644 {} \;
  chown -R www:www "${CURRENT_DIR}/${PATCH_FILES_DIR}"
  #rsync -avh --keep-dirlinks "${CURRENT_DIR}/${PATCH_FILES_DIR}/opt/gate1/www" "/opt/gate1/"
  cp -Rfv "${CURRENT_DIR}/${PATCH_FILES_DIR}/opt/gate1/www" "/opt/gate1/"
}

###########################################################
# 이전에 백업된 파일에 대한 복구 실행
###########################################################
func_run_restore() {
  echo "###########################################################"
  echo "#"
  echo "# func_run_restore"
  echo "#"
  echo "###########################################################"

  # 패치 파일이 정상적으로 존재하는지 검사한다.
  for TMPV in ${PATCH_FILES[@]}
  do
    FILE_PATH=$(dirname ${TMPV})
    FILE_NAME=$(basename ${TMPV})
    if [ ! -f "${CURRENT_DIR}/${1}${TMPV}" ]
    then
      echo "${CURRENT_DIR}/${1}${TMPV} not found."
      exit 1
    fi
  done

  # 복구 실행
  find "${CURRENT_DIR}/${1}" -type d -exec chmod 755 {} \;
  find "${CURRENT_DIR}/${1}" -type f -exec chmod 644 {} \;
  chown -R www:www "${CURRENT_DIR}/${1}"
  cp -Rfv "${CURRENT_DIR}/${1}/opt/gate1/www" "/opt/gate1/"
}

###########################################################
# 패치를 적용 후 정리
###########################################################
func_finish() {
  echo "###########################################################"
  echo "#"
  echo "# func_finish"
  echo "#"
  echo "###########################################################"

  chown -R www:www /opt/gate1/www
  chown -R www:www /opt/gate1/sbin/lib
}

case "$1" in
  "make_patch")
    func_prepare
    func_make_patch
    func_continue
    ;;
  "patch0")
    func_prepare
    func_backup
    func_continue
    func_run_patch0
    func_continue
    func_finish
    ;;
  "patch1")
    func_prepare
    func_backup
    func_continue
    func_run_patch1
    func_continue
    func_finish
    ;;
  "patch2")
    func_prepare
    func_backup
    func_continue
    func_run_patch2
    func_continue
    func_finish
    ;;
  "restore")
    if [ -z "$2" ]
    then
      echo "backup directory not found."
      exit
    fi
    func_run_restore "$2"
    func_continue
    func_finish
    ;;
  *)
    echo "Usage: $0 {make_patch|patch0|patch1|patch2|restore}"
    echo ""
    echo "  make_patch: 운영 디렉토리에서 파일을 가져와서 패치를 만듦-patch2 옵션으로 패치 가능."
    echo "  patch0: 패치 파일이 현재 디렉토리에 있음."
    echo "  patch1: 패치 파일이 ${PATCH_FILES_DIR} 내에 있음."
    echo "  patch2: 패치 파일이 ${PATCH_FILES_DIR} 내에 /디렉토리 기준의 트리형태로 있음."
    echo "  restore: 백업본으로 원상복구 시킨다. (백업 디렉토리를 지정해야 한다)"
    echo
    echo "  ex)"
    echo "    $0 make_patch"
    echo "    $0 patch0"
    echo "    $0 restore backup.20210917_093551"
    exit 1
esac
위로 스크롤