iBetter Books
수정

프로젝트 4: 사용자 관리 자동화

마지막 프로젝트는 사용자 관리 자동화입니다. 학기 시작마다 수십 명의 학생 계정을 만들거나, 퇴사자 계정을 일괄 삭제해야 하는 상황을 생각해봅시다. 한 명씩 손으로 하면 시간도 오래 걸리고 실수도 납니다.

이 스크립트는 CSV 파일에서 사용자 목록을 읽어 계정을 일괄 생성하거나 삭제합니다. --dry-run 모드로 실제 실행 전에 결과를 미리 확인할 수 있습니다.

요구사항

  • CSV 파일에서 이름, 그룹, 쉘, 비밀번호를 읽습니다.
  • useradd, userdel로 계정을 생성/삭제합니다.
  • chpasswd로 초기 비밀번호를 설정합니다.
  • --dry-run 모드를 지원합니다.
  • 위험 작업 전 확인 프롬프트를 표시합니다.
  • 성공/실패/건너뜀 수를 포함한 리포트를 출력합니다.

CSV 샘플 데이터

# 새 파일: /home/ubuntu/scripts/users.csv
# 형식: username,fullname,group,shell,password
# 주석은 #으로 시작, 빈 줄은 무시

student01,김민준,students,/bin/bash,Ch@nge1234
student02,이서윤,students,/bin/bash,Ch@nge1234
student03,박지호,students,/bin/bash,Ch@nge1234
ta01,최아린,teaching_assistants,/bin/bash,TA@secure99
ta02,정도윤,teaching_assistants,/bin/bash,TA@secure99
guest01,홍길동,guests,/bin/sh,Guest@2026

사용자 관리 스크립트

#!/usr/bin/env bash# 새 파일: /home/ubuntu/scripts/user_manager.shset -euo pipefail# ==============================================================# 상수와 전역 변수# ==============================================================SCRIPT_NAME=$(basename "$0")DRY_RUN=falseACTION=""CSV_FILE=""# 리포트 카운터COUNT_SUCCESS=0COUNT_FAILED=0COUNT_SKIP=0# ==============================================================# 사용법 출력# ==============================================================usage() {    cat << EOF사용법: $SCRIPT_NAME <동작> <CSV파일> [옵션]동작:  create    CSV 파일의 사용자 계정 생성  delete    CSV 파일의 사용자 계정 삭제옵션:  --dry-run   실제로 실행하지 않고 결과만 미리 확인  -h, --help  이 도움말 출력예시:  $SCRIPT_NAME create users.csv  $SCRIPT_NAME create users.csv --dry-run  $SCRIPT_NAME delete users.csv --dry-runEOF}# ==============================================================# 인수 파싱# ==============================================================if [[ $# -lt 2 ]]; then    usage    exit 1fiACTION="$1"CSV_FILE="$2"shift 2while [[ $# -gt 0 ]]; do    case "$1" in        --dry-run) DRY_RUN=true ;;        -h|--help) usage; exit 0 ;;        *) echo "알 수 없는 옵션: $1" >&2; usage; exit 1 ;;    esac    shiftdone# ==============================================================# 유효성 검사# ==============================================================if [[ "$ACTION" != "create" && "$ACTION" != "delete" ]]; then    echo "ERROR: 동작은 'create' 또는 'delete'여야 합니다." >&2    exit 1fiif [[ ! -f "$CSV_FILE" ]]; then    echo "ERROR: CSV 파일을 찾을 수 없습니다: $CSV_FILE" >&2    exit 1fiif [[ $EUID -ne 0 && "$DRY_RUN" == false ]]; then    echo "ERROR: 사용자 관리는 루트 권한이 필요합니다. sudo로 실행하세요." >&2    exit 1fi# ==============================================================# dry-run 또는 실제 실행 래퍼# ==============================================================run_cmd() {    if "$DRY_RUN"; then        echo "  [DRY-RUN] $*"    else        "$@"    fi}# ==============================================================# 확인 프롬프트# ==============================================================confirm() {    local prompt="$1"    local response    read -rp "$prompt [y/N] " response    [[ "${response,,}" == "y" ]]}# ==============================================================# 사용자 생성 함수# ==============================================================create_user() {    local username="$1"    local fullname="$2"    local group="$3"    local shell="$4"    local password="$5"    # 이미 존재하는 사용자 건너뜀    if id "$username" &>/dev/null; then        echo "  [건너뜀] $username - 이미 존재합니다."        ((COUNT_SKIP++))        return    fi    echo "  [생성] $username ($fullname) 그룹=$group 쉘=$shell"    # 그룹이 없으면 생성    if ! getent group "$group" &>/dev/null; then        run_cmd groupadd "$group"    fi    # 사용자 계정 생성    if run_cmd useradd \        --create-home \        --shell "$shell" \        --ingroup "$group" \        --comment "$fullname" \        "$username"; then        # 비밀번호 설정        if "$DRY_RUN"; then            echo "  [DRY-RUN] echo '${username}:${password}' | chpasswd"        else            echo "${username}:${password}" | chpasswd        fi        echo "  [완료] $username 생성 성공"        ((COUNT_SUCCESS++))    else        echo "  [실패] $username 생성 실패"        ((COUNT_FAILED++))    fi}# ==============================================================# 사용자 삭제 함수# ==============================================================delete_user() {    local username="$1"    # 존재하지 않는 사용자 건너뜀    if ! id "$username" &>/dev/null; then        echo "  [건너뜀] $username - 존재하지 않습니다."        ((COUNT_SKIP++))        return    fi    echo "  [삭제] $username"    # --remove: 홈 디렉토리와 메일 박스도 삭제    if run_cmd userdel --remove "$username" 2>/dev/null; then        echo "  [완료] $username 삭제 성공"        ((COUNT_SUCCESS++))    else        echo "  [실패] $username 삭제 실패"        ((COUNT_FAILED++))    fi}# ==============================================================# 메인 실행# ==============================================================echo ""echo "===== 사용자 관리 스크립트 ====="echo "동작: $ACTION"echo "파일: $CSV_FILE"if "$DRY_RUN"; then    echo "모드: DRY-RUN (실제 변경 없음)"fiecho ""# 삭제는 위험 작업 — 확인 요청if [[ "$ACTION" == "delete" ]] && ! "$DRY_RUN"; then    if ! confirm "사용자 계정과 홈 디렉토리를 삭제합니다. 계속하시겠습니까?"; then        echo "취소되었습니다."        exit 0    fifiecho "--- 처리 시작 ---"# CSV 파일 파싱while IFS=',' read -r username fullname group shell password; do    # 빈 줄과 주석(#) 건너뜀    [[ -z "$username" || "$username" =~ ^[[:space:]]*# ]] && continue    # 앞뒤 공백 제거    username="${username// /}"    fullname="${fullname//,/}"    case "$ACTION" in        create) create_user "$username" "$fullname" "$group" "$shell" "$password" ;;        delete) delete_user "$username" ;;    esacdone < "$CSV_FILE"echo ""echo "--- 처리 완료 ---"echo "성공: ${COUNT_SUCCESS}개"echo "실패: ${COUNT_FAILED}개"echo "건너뜀: ${COUNT_SKIP}개"echo ""

실행

chmod +x /home/ubuntu/scripts/user_manager.sh

dry-run으로 먼저 확인합니다.

sudo /home/ubuntu/scripts/user_manager.sh create /home/ubuntu/scripts/users.csv --dry-run

실행 결과입니다.

===== 사용자 관리 스크립트 =====
동작: create
파일: /home/ubuntu/scripts/users.csv
모드: DRY-RUN (실제 변경 없음)

--- 처리 시작 ---
  [생성] student01 (김민준) 그룹=students 쉘=/bin/bash
  [DRY-RUN] useradd --create-home --shell /bin/bash --ingroup students --comment 김민준 student01
  [DRY-RUN] echo 'student01:Ch@nge1234' | chpasswd
  [완료] student01 생성 성공
  [생성] student02 (이서윤) 그룹=students 쉘=/bin/bash
  [DRY-RUN] useradd --create-home --shell /bin/bash --ingroup students --comment 이서윤 student02
  [DRY-RUN] echo 'student02:Ch@nge1234' | chpasswd
  [완료] student02 생성 성공
  ...

--- 처리 완료 ---
성공: 6개
실패: 0개
건너뜀: 0개

문제 없으면 실제로 실행합니다.

sudo /home/ubuntu/scripts/user_manager.sh create /home/ubuntu/scripts/users.csv

계정이 만들어졌는지 확인합니다.

grep -E "student|ta0|guest" /etc/passwd
student01:x:1001:1001:김민준:/home/student01:/bin/bash
student02:x:1002:1001:이서윤:/home/student02:/bin/bash
student03:x:1003:1001:박지호:/home/student03:/bin/bash
ta01:x:1004:1002:최아린:/home/ta01:/bin/bash
ta02:x:1005:1002:정도윤:/home/ta02:/bin/bash
guest01:x:1006:1003:홍길동:/home/guest01:/bin/sh

삭제도 확인 후 실행합니다.

# dry-run으로 먼저 확인sudo /home/ubuntu/scripts/user_manager.sh delete /home/ubuntu/scripts/users.csv --dry-run# 실제 삭제 (확인 프롬프트 표시됨)sudo /home/ubuntu/scripts/user_manager.sh delete /home/ubuntu/scripts/users.csv

삭제 실행 시 확인 프롬프트가 나타납니다.

사용자 계정과 홈 디렉토리를 삭제합니다. 계속하시겠습니까? [y/N] y

y를 입력하면 진행됩니다.