우분투 20.04를 사용하고 있습니다. 이 스크립트를 실행하려고 합니다 inotifywait
. 아이디어는 디렉토리가 변경될 때마다 파일을 이동하는 것입니다 dir
. target
스크립트는 명령줄을 통해 자동 또는 수동으로 시작할 수 있는 셸 파일입니다.
#!/usr/bin/env bash
dir=/mnt/test1/test/ #ftp point of mount
target=/var/www/html/local/ #normal directory on filesystem
inotifywait -m "$dir" --format "%w%f" -e create -e moved_to |
while read path action file; do
mv "$file" "$target"
done
그리고 이동할 파일은 *.txt
형식이어야 합니다. inotify가 지켜보고 있지만 ftp 클라이언트를 사용하여 파일을 넣고 dir
inotify가 파일을 이동할 때까지 기다리면 target
파일에 아무 일도 일어나지 않습니다.
나는 이것을 참고로 사용하고 있습니다 :https://unix.stackexchange.com/a/86292/425161
답변1
불행하게도 이 inotify
API는 원격 파일 시스템을 모니터링하는 데 사용할 수 없습니다.
~에서man 7 inotify
:
Inotify는 파일 시스템 API를 통해 사용자 공간 프로그램에 의해 트리거된 이벤트만 보고합니다. 따라서 네트워크 파일 시스템에서 발생하는 원격 이벤트를 캡처하지 않습니다. (응용 프로그램은 이러한 이벤트를 캡처하기 위해 파일 시스템 폴링으로 대체해야 합니다.)
관련 질문:
- 원격 파일 시스템(특히 WebDAV)에서 inotify를 사용할 수 있는 방법이 있습니까?
- SSHFS를 통해 마운트된 폴더 모니터링
- SSHFS를 통해 inotify 또는 명명된 파이프를 사용하는 방법은 무엇입니까?
즉, 귀하의 질문에 있는 스크립트가 예상대로 작동하지 않습니다.
"%w%f"
as의 출력 형식을 사용하는 아이디어는 inotifywait
청취된 파일 시스템 이벤트를 트리거한 파일에 대한 전체 경로를 루프의 명령에 제공하는 것입니다. 모니터링되는 파일의 %w
경로( $dir
디렉토리)와 %f
이벤트를 발생시킨 파일의 (기본) 이름으로 확장됩니다.
따라서 inotifywait
캡처하는 각 이벤트에 대해 전체 경로만 내보내집니다. 반면에 귀하의 read
명령이 내려졌습니다.삼채워질 변수: path
, action
및 file
. 기본적으로 read
읽기 행은 문자를 기준으로 분할되고 IFS
결과 토큰은 인수로 지정된 이름에 할당됩니다. 첫 번째 토큰은 첫 번째 이름에 할당되고 두 번째 토큰은 두 번째 이름 등. (그리고 두 번째 이름 뒤에 이름보다 토큰이 더 많으면 남은 모든 토큰이 성에 할당됩니다.)
쉽게 확인할 수 있듯이 코드에서 감시 이벤트를 트리거하는 모든 파일의 전체 경로가 할당됩니다 path
(공백 문자가 포함되지 않은 경우).
$ inotifywait -m --format "%w%f" -e create -e moved_to /tmp/test |
while read path action file; do
printf 'path: "%s"; action: "%s"; file: "%s"\n' "$path" "$action" "$file"
done
# Type "touch /tmp/test/foo" in a different terminal
path: "/tmp/test/foo"; action: ""; file: ""
게다가 기사에도 나와 있듯이다른 답변서명된 Q&A에서는 듣는 close_write
것이 아니라 이벤트를 들어야 합니다 create
. 당신이 찾고 있는 것은 다음과 같습니다:
inotifywait -m -q --format "%w%f" -e close_write -e moved_to -- "$dir" |
while IFS= read -r src; do
if [ "${src##*.}" = 'txt' ]; then
mv -- "$src" "$target"
fi
done
-r
read
백슬래시 이스케이프 시퀀스를 해석하지 않도록 지시합니다 . 파일 이름 끝의 공백 문자가 잘리는 것을 IFS=
방지하는 데 사용됩니다 read
(이름이 공백이나 탭으로 끝나는 경우를 처리하기 위해).
이름에 개행 문자가 포함된 파일의 경우에는 여전히 실패합니다.