스크립트 설계

  1. 로그 함수 정의:
    • log 함수는 현재 시간과 함께 로그 메시지를 지정된 로그 파일에 기록합니다.
  2. PID 파일 체크:
    • 스크립트가 이미 실행 중인지 확인하고, 실행 중인 경우 스크립트를 종료합니다.
  3. PID 파일 생성 및 종료 시 삭제:
    • 현재 스크립트의 PID를 PID 파일에 저장하고, 스크립트 종료 시 PID 파일을 삭제하도록 설정합니다.
  4. 무한 루프:
    • WATCH_DIR 디렉토리가 존재하는지 확인합니다.
    • find 명령어를 사용하여 WATCH_DIR와 하위 디렉토리의 모든 파일을 찾습니다.
    • 각 파일의 크기와 수정 시간을 측정하여 일정 시간 동안 변경되지 않았으면 파일을 복사합니다.
    • cp 명령어를 사용하여 파일을 DEST_DIR로 복사한 후, 복사된 파일의 크기가 원본과 동일한 경우에만 원본 파일을 삭제합니다.
    • rm 명령어를 사용하여 원본 파일을 삭제합니다. 삭제가 실패할 경우 로그에 기록합니다.
  5. 하위 디렉토리 포함:
    • find "$WATCH_DIR" -type f 명령어를 사용하여 하위 디렉토리의 파일도 포함하여 검색합니다.

이 스크립트는 파일 복사가 완료된 후 원본 파일을 삭제하므로 데이터 손실의 위험을 줄일 수 있습니다. 로그 파일을 주기적으로 확인하여 스크립트의 동작 상태를 모니터링하는 것이 좋습니다.

#!/bin/bash

WATCH_DIR="/downloads/completed"
DEST_DIR="/home/completed"
LOG_FILE="/home/file_watch.log"
PIDFILE="/var/run/file_watch.pid"

# 로그 함수 정의
log() {
    local message="$1"
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $message" >> "$LOG_FILE"
}

# PIDFILE 체크
if [ -f "$PIDFILE" ]; then
    echo "Script is already running with PID $(cat $PIDFILE). Exiting."
    exit 1
fi

# PIDFILE 생성
echo $$ > "$PIDFILE"

# 종료 시 PIDFILE 삭제
trap 'rm -f "$PIDFILE"; exit' INT TERM EXIT

# 무한 루프 시작
while true; do
    # WATCH_DIR이 존재하는지 확인
    if [ ! -d "$WATCH_DIR" ]; then
        log "Watch directory $WATCH_DIR does not exist."
        rm -f "$PIDFILE"
        exit 1
    fi
    
    # 현재 디렉토리에서 하위 디렉토리를 포함한 파일 목록을 가져옴
    find "$WATCH_DIR" -type f | while IFS= read -r file; do
        # 파일이 존재하는지 확인
        if [ ! -e "$file" ]; then
            log "File $file does not exist."
            continue
        fi
        
        # 파일 크기 측정
        initial_size=$(stat -c%s "$file")
        initial_mtime=$(stat -c%Y "$file")
        # 파일을 잠시 기다린 후 다시 크기와 수정 시간을 측정
        sleep 300
        new_size=$(stat -c%s "$file")
        new_mtime=$(stat -c%Y "$file")
        
        # 파일 크기와 수정 시간이 변하지 않으면 복사 후 원본 삭제
        if [ "$initial_size" -eq "$new_size" ] && [ "$initial_mtime" -eq "$new_mtime" ]; then
            # 목적지 파일 경로
            dest_file="$DEST_DIR/$(basename "$file")"
            # 파일 복사
            cp "$file" "$dest_file" 2>> "$LOG_FILE"
            if [ $? -eq 0 ]; then
                # 복사 성공 후 원본 파일 삭제
                if [ "$initial_size" -eq "$(stat -c%s "$dest_file")" ]; then
                    rm "$file" 2>> "$LOG_FILE"
                    if [ $? -eq 0 ]; then
                        log "Moved $(basename "$file") to $DEST_DIR"
                    else
                        log "Failed to delete the original file $(basename "$file") after copy."
                    fi
                else
                    log "Size mismatch after copying $(basename "$file") to $DEST_DIR."
                fi
            else
                log "Failed to copy $(basename "$file") to $DEST_DIR. Check log for details."
            fi
        else
            log "File $file is still being modified or its size changed."
        fi
    done

    sleep 10
done

위의 스크립트가 file_watch.sh 라고 할 때, 백그라운드로 실행시키고 싶다면,

sudo nohup ./file_watch.sh &

백그라운드로 실행되 있는 스크립트를 확인하고자 한다면,

sudo ps aux | grep file_watch.sh

백그라운드로 실행하고 있는 스크립트를 종료시키고자 한다면,

sudo pkill -f file_watch.sh

그런데, 백그라운드 실행 방식은 세션이 종료되면 함께 종료될 수 있다.

따라서, 서비스로 등록시켜서 재부팅이 된 후에도 실행이 되도록 하자.

sudo nano /etc/systemd/system/file_watch.service

아래와 같이 입력하고 저장한다.

[Unit]
Description=File Watch Script

[Service]
ExecStart=/path/to/your/file_watch.sh
Restart=always
User=root

[Install]
WantedBy=multi-user.target

아래 명령어를 차례대로 수행하여 활성화 시켜주자.

sudo systemctl daemon-reload
sudo systemctl enable file_watch.service
sudo systemctl start file_watch.service

file_watch 서비스의 실행 여부는 아래 명령으로 확인한다.

sudo service file_watch status

#파일감시 #파일이동 #리눅스 #쉘스크립트

Author: 모요
댓글

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

*

©2024 MOYO Blog with DAON Consulting Co,LTD.

CONTACT US

We're not around right now. But you can send us an email and we'll get back to you, asap.

보내는 중입니다..

로그인하세요.

계정 내용을 잊으셨나요 ?