Linux에서 새 파일이 디렉토리에 추가될 때 작업을 수행하는 방법

이 설명서에서는 리눅스 파일 시스템의 이벤트 알림 기능을 활용하여 특정 디렉토리에 새로운 파일이 생성될 때마다 알림을 받는 방법을 안내합니다. 이러한 알림을 트리거로 사용하여 시스템 내에서 다양한 일반 작업을 자동화할 수 있습니다.

우리는 특정 디렉토리를 주시하고, 새로 추가된 파일들을 대상으로 작동하는 스크립트를 개발할 것입니다. 각 파일은 탐지되는 즉시 gzip 형식으로 압축되어 별도의 지정된 디렉토리로 옮겨집니다. 이 스크립트는 `inotify-tools`라는 유틸리티를 통해 inotify 하위 시스템을 이용합니다. 먼저 필요한 도구를 설치하고 작동 방식을 실험해 보겠습니다.

`inotify-tools`와 `gzip` 설치하기

Ubuntu 또는 Debian 계열의 리눅스 배포판을 사용하시는 경우, `apt-get` 명령어를 사용하여 패키지를 설치할 수 있습니다. 다른 리눅스 배포판을 사용하시는 경우에는 해당 배포판의 패키지 관리 도구를 이용해주세요.

sudo apt-get install inotify-tools gzip

`inotify-tools` 작동 방식 실험하기

가장 먼저, 특정 디렉토리를 관찰하면서 새로운 파일이 추가될 때 발생하는 이벤트들을 확인해 보겠습니다. `inotify-tools`에 포함된 `inotifywatch`라는 도구를 사용할 것입니다. 우선, “incoming”이라는 새로운 디렉토리를 생성합니다.

mkdir incoming

다음 명령을 실행하여 이 디렉토리의 감시를 시작합니다.

inotifywatch -v incoming

이 명령은 inotify가 “incoming” 디렉토리에서 발생하는 모든 파일 시스템 이벤트를 감시하도록 지시합니다. `-v` 옵션은 도구가 수행하는 작업에 대한 추가 정보를 출력하도록 합니다. 시간 초과 옵션(`-t`)을 지정하지 않았으므로 명령은 `Ctrl+C`를 눌러 강제로 종료할 때까지 이벤트 수집을 계속합니다. 현재 터미널 화면은 아래와 유사해야 합니다.

새로운 터미널 창(또는 탭)을 열고, `incoming` 디렉토리로 이동합니다. `touch` 명령어를 사용하여 “newfile”이라는 새로운 파일을 만듭니다.

cd incoming/
touch newfile

이제 첫 번째 터미널 창으로 돌아와 `CTRL+C`를 눌러 `inotifywatch`를 중지합니다.

콘솔에는 “create”, “open”, “attrib”, “close_write” 이벤트들이 기록된 테이블이 나타납니다. 이 네 가지 이벤트는 `touch` 명령을 사용하여 새로운 파일을 생성하고, 파일 접근 속성을 설정하고, 널 종료 문자를 쓰기 위해 파일을 열고, 그 후 파일을 닫을 때 발생합니다. 이것들은 `inotify-tools`를 사용하여 파일 시스템에서 모니터링할 수 있는 수많은 이벤트 중 일부에 불과합니다. `inotifywatch`의 매뉴얼 페이지에서 전체 목록을 확인할 수 있습니다.

우리의 목적을 위해, 우리는 다음 두 가지 이벤트에만 관심을 갖습니다.

  • “create” – 대상 디렉토리에 파일이 생성될 때.
  • “moved_to” – 다른 위치에서 파일이 대상 디렉토리로 이동될 때.

이제 `inotifywatch`를 다시 실행하되, 이번에는 이 두 가지 이벤트만 모니터링하도록 지정합니다. 첫 번째 터미널 창에서 다음 명령을 실행합니다.

inotifywatch -v -e create -e moved_to incoming

두 번째 터미널 창이나 탭에서, 새로운 파일을 만들고, 내용을 변경한 후, 다른 위치에서 대상 디렉토리로 파일을 이동해 보겠습니다. 이 모든 명령은 홈 디렉토리에서 실행해야 합니다.

touch incoming/created
echo Testing123 >> incoming/created
touch /tmp/created2
mv /tmp/created2 incoming/

첫 번째 터미널 창으로 돌아가서 `CTRL+C`를 눌러 `inotifywatch`를 중지합니다. 다음 출력이 표시됩니다.

“created”라는 파일을 만들고, “created2″라는 기존 파일을 이동시키는 두 가지 이벤트만 기록되었습니다. 파일 내용 수정과 같은 다른 작업들은 무시되었습니다.

디렉토리 감시 및 작업 실행

어떤 이벤트를 감시해야 하는지 확인했으므로, `inotifywait`라는 다른 도구를 사용하여 파일이 대상 디렉토리에서 생성되거나 이동할 때까지 실행을 일시 중지시킬 수 있습니다. `inotifywatch`에서 사용했던 것과 동일한 인수를 사용하고, 파일 이름을 작업에 사용하기 위한 형식도 지정합니다.

시작하기 전에 이미 처리된 파일을 보관할 디렉토리가 필요합니다. “processed”라는 디렉토리를 만듭니다.

mkdir processed

다음으로, “watch-incoming.sh”라는 새로운 스크립트를 만들고, 아래에 나열된 내용을 추가합니다.

#!/bin/bash

TARGET=~/incoming/
PROCESSED=~/processed/

inotifywait -m -e create -e moved_to --format "%f" $TARGET 
        | while read FILENAME
                do
                        echo Detected $FILENAME, moving and zipping
                        mv "$TARGET/$FILENAME" "$PROCESSED/$FILENAME"
                        gzip "$PROCESSED/$FILENAME"
                done

이 스크립트는 `-m` 옵션과 함께 `inotifywait` 명령을 실행합니다. 이렇게 하면 명령어가 변경 사항을 무기한 감시합니다. 새로운 이벤트가 감지될 때마다 파일 이름이 읽기 명령에 전달되고, “FILENAME” 변수에 삽입됩니다. while 루프 아래 블록이 실행되어 파일이 먼저 “processed” 디렉토리로 이동되고, 이후 gzip 형식으로 압축됩니다. 원본 파일은 압축된 파일로 대체되며, 파일 이름은 “.gz”로 끝납니다.

이 스크립트에 실행 권한을 부여하고 홈 디렉토리에서 실행해 보겠습니다.

chmod u+x watch-incoming.sh
./watch-incoming.sh

두 번째 터미널 창을 열고 “incoming” 디렉토리에 새로운 파일을 생성합니다. 감지되는 이벤트의 결과를 확인하려면 “incoming” 및 “processed” 디렉토리의 내용을 모두 나열합니다.

“incoming” 디렉토리에 복사한 원본 텍스트 파일은 스크립트에 의해 감지되어 “processed” 디렉토리로 이동된 후, gzip을 사용하여 압축되었습니다.

이제 디렉토리에 도착하는 새로운 파일을 감지할 수 있으므로, 다양한 흥미로운 작업을 수행할 수 있습니다. 예를 들어, 이미지 파일에 워터마크를 추가하거나, 원본 비디오를 MP4 형식으로 압축하거나, 새로 나타나는 모든 파일을 Amazon S3 버킷에 업로드할 수 있습니다. 이 스크립트는 자신만의 워크플로를 실행하고 시스템에서 일반 작업을 자동화하기 위한 좋은 출발점입니다.