디렉토리에 있는 프로세스 파일 [중복]

디렉토리에 있는 프로세스 파일 [중복]

중복 가능성:
디렉터리 내용이 업데이트될 때 명령을 실행하는 방법은 무엇입니까?

나는 1분마다 디렉터리에서 파일을 찾는 간단한 etl 프로세스를 작성하려고 합니다. 파일이 있으면 (스크립트를 통해) 원격 시스템에 로드한 다음 삭제합니다.

상황을 복잡하게 만들면 로드하는 데 1분 이상 걸릴 수 있습니다. 이 문제를 해결하기 위해 모든 파일을 임시 처리 디렉터리로 이동하고 그곳에서 작업한 다음 거기에서 삭제할 수 있다고 생각했습니다. 또한 명령줄 스크립트 작성을 더 잘하려고 노력하면서 더 우아한 솔루션을 시도하고 있습니다. 먼저 작업을 수행하기 위해 다음과 같은 간단한 스크립트를 작성했습니다.

#!/bin/bash

for i in ${find /home/me/input_files/ -name "*.xml"}; do
FILE=$i;
done;
BASENAME=`basename $FILE`
mv $FILE /tmp/processing/$BASENAME
myscript.sh /tmp/processing/$BASENAME other_inputs
rm /tmp/processing/$BASENAME

스크립트는 처리 디렉터리에서 파일을 거의 즉시 제거하고(중복 처리 문제 방지) 최종적으로 자체 정리하여 그 사이에 파일을 처리할 수 있도록 합니다.

그러나 이것은 결국 U/Linux이다. 거대한 스크립트를 유지 관리하기보다는 파이프를 연결하고 이동하여 이 모든 작업을 한 줄로 수행할 수 있어야 한다고 생각합니다.

또한 동시 프로세스에 병렬성을 사용하는 것도 장점이 될 수 있습니다.

부록: 일종의 FIFO 대기열이 이 질문에 대한 답이 될 수도 있습니다. 아니면 cron 대신 다른 종류의 디렉토리 감시자가 있을 수도 있습니다. 나는 내 작은 대본보다 더 우아한 제안에 열려 있습니다. 유일한 문제는 "입력 디렉터리"의 파일이 실제로 기록되기 전에 터치된다는 점입니다. -size -0은 실제 파일을 처리하는 데에만 필요합니다.

답변1

작은 처리 스크립트를 작성하고 병렬 처리를 위해 GNU Parallel을 사용할 수 있는 것처럼 들립니다.

http://www.gnu.org/software/parallel/man.html#example__gnu_parallel_as_dir_processor

그래서 이렇게 :

inotifywait -q -m -r -e CLOSE_WRITE --format %w%f my_dir |
  parallel 'mv {} /tmp/processing/{/};myscript.sh /tmp/processing/{/} other_inputs; rm /tmp/processing/{/}'

자세히 알아보려면 소개 비디오를 시청하세요.http://pi.dk/1

편집하다:

길이가 0인 파일을 처리하려면(즉, 무시) myscript.sh가 필요합니다.

이를 피할 수 있다면 touch다음과 같이 할 수도 있습니다.

inotifywait -q -m -r -e CLOSE_WRITE --format %w%f my_dir |
  parallel myscript.sh {} other_inputs

GNU Parallel 설치는 매우 간단합니다.

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel

답변2

먼저 스크립트는 하나의 파일(목록의 마지막 파일)에서 작동합니다. 또한 한 줄짜리 표현이 항상 적절하거나 우아하지는 않다고 생각합니다. Cron은 뒤에서 많은 작업을 수행하므로 실패한 작업을 확인할 수 있어야 합니다. cron을 "자주" 실행하는 것은 문제가 될 수 있습니다. 수십 개의 이러한 프로세스가 실행되어 모두 대기열에 있는 파일을 처리하려고 시도하므로 시스템 속도가 느려질 수 있습니다.

이것이 내가 할 일이다.

Dir="$HOME/input_files"   # never hardcode when you have variables
for filename in "$Dir"/*.xml; do
    # is the file non-empty AND is it still there, or may caught by another
    # process
    if [ -s "$filename" ]; then
        # move files locally will be faster than crossing filesystems to /tmp
        mkdir -p "$Dir/.processing"
        # temp name should use pid, just in case another input with the same name comes in
        tempname="$Dir/.processing/`basename $filename .xml`.$$"
        mv "$filename" "$tempname"
        # send stdout and stderr to a .output file
        myscript.sh "$tempname" other_inputs > "$tempname.output" 2>&1
        rc=$?
        if [ $rc -eq 0 ]; then
            rm "$tempname" "$tempname.output"
        else
            echo "Error processing $filename; rc=$rc" >&2
            echo "File in $tempname" >&2
        fi
    done

이렇게 하면 처리 후 파일이 삭제되거나 .processing오류가 발생한 경우 명령 출력이 포함된 디렉터리에 파일이 그대로 유지됩니다. 위 명령은 아무 것도 제한하지 않지만 여러 명령이 서로 간섭하지 않고 실행되도록 허용합니다. 향상을 위해 상당히 효율적인 작업 대기열을 만드는 방법에 대한 다른 질문이 있습니다.

답변3

사용이노티파이(7)cron을 통해 폴링하는 대신 들어오는 디렉터리를 모니터링하는 인터페이스입니다. inotify-tools는 시스템 호출 인터페이스에 대해 코드를 작성하지 않으려는 경우 디렉터리를 감시하는 데 사용할 수 있는 inotifywait 프로그램을 제공합니다.

관련 정보