![inotifywait는 감시 디렉터리의 새 폴더를 무시합니다.](https://linux55.com/image/203755/inotifywait%EB%8A%94%20%EA%B0%90%EC%8B%9C%20%EB%94%94%EB%A0%89%ED%84%B0%EB%A6%AC%EC%9D%98%20%EC%83%88%20%ED%8F%B4%EB%8D%94%EB%A5%BC%20%EB%AC%B4%EC%8B%9C%ED%95%A9%EB%8B%88%EB%8B%A4..png)
폴더(/shares/Photos)를 보기 위해 inotifywait를 사용하려고 하는데 해당 폴더에 추가된 jpg가 감지되면 하위 디렉터리($small_dir)로 크기를 조정해야 합니다. 사진 관리자 아래에는 많은 jpg 하위 폴더가 있습니다.
나무는 이렇게 생겼어요
shares
-Photos
-Folder 1
-Folder 2
.
.
.
기본적으로 누군가가 이미지를 복사할 때마다 folder 1
새 하위 폴더를 만든 다음 이미지 크기를 조정하고 더 작은 버전을 해당 폴더에 넣어야 합니다.
그러면 트리는 다음과 같이 됩니다.
shares
-Photos
-Folder 1
-Resized
-Folder 2
.
.
.
지금까지 내 코드는 다음과 같습니다.
inotifywait -mr --timefmt '%m/%d/%y %H:%M' --format '%T %w %f' -e close_write /shares/Photos --includei "\.jpg|\.jpeg" |
while read -r date time dir file; do
changed_abs=${dir}${file}
small_dir=${dir}${target}/
printf "\nFile $changed_abs was changed or created\n dir=$dir \n file=$file \n small_dir=$small_dir \n"
# Check if the $small_directory exists, if not create it.
if [ -d "$small_dir" -a ! -h "$small_dir" ]
then
echo "$small_dir found, nothing to do."
else
echo "Creating $small_dir"
mkdir $small_dir
chmod 777 $small_dir
fi
# Check to see if the file is in $small_dir, if it is, do nothing.
if [ "$dir" = "$small_dir" ]; then
printf "\nFile is in the $small_dir folder, nothing to do\n"
else
printf "\nResizing file into the $small_dir folder\n"
# Code to resize the image goes here.
fi
done
Photos
기본적으로는 작동하지만, 스크립트가 실행되는 동안 새 하위 폴더를 생성 하면 inotifywait가 이를 무시하고 아무 작업도 하지 않는다는 벽에 부딪혔습니다 .
close_write
로 교체해 보았지만 create
별 차이가 없었고 여기서 어디로 가야할지 정말 모르겠습니다.
어떤 조언이나 도움이라도 대단히 감사하겠습니다.
답변1
OP는 다음을 사용하고 있습니다.
inotifywait -mr --timefmt '%m/%d/%y %H:%M' --format '%T %w %f' -e close_write /shares/Photos --includei "\.jpg|\.jpeg" |
관련된 문서--includei
말했다 (굵은 강조 내):
--includei <pattern>
이벤트 처리이름이 지정된 POSIX 정규 표현식과 일치하는 파일의 하위 집합에만 적용되며 대소문자를 구분하지 않습니다.
이것은 "표시 이벤트"가 아니라 "이벤트 처리"입니다. 실제로 이는 이름에 포함되거나 처리될 .jpg
디렉터리에 대한 이벤트 만 의미합니다..jpeg
발생했지만 필터와 일치하지 않는 디렉터리 생성 이벤트는 처리되지 않으므로 inotifywait
호출되지 않습니다.inotify_add_watch(2)
이번 사건과 그 이후에 일어난 모든 일에 대해. 따라서 이 하위 디렉터리에서는 이벤트가 모니터링되지 않습니다.
--includei
"이 정규 표현식에 대해서만 이벤트를 처리합니다 .아니면임의의 디렉토리로".
고쳐 쓰다: 제안된 솔루션
따라서 작동하게 만드는 방법은 명령 외부를 필터링해야 하는 것 같습니다. grep
tty가 아닌 경우 GNU는 출력을 버퍼링하므로 --line-buffered
.
이는 사용자 입력(예: 파일 이름의 공백)의 영향을 받습니다. 이를 완화하려면 /
디렉터리와 파일 이름 사이에 구분 기호를 사용해야 합니다(파일 이름에는 영향을 미치지 않음). 디렉토리 부분에는 편리하게 후행이 포함되어 있으므로 /
형식 문자열에서 공백을 제거하는 것만으로도 충분합니다(예를 들어 추가 변수 처리 및 재사용도 가능 changed_abs
). 그동안 파일명 필터링 의도를 수정하고 있습니다끝문자열이 jpg
있거나 jpeg
, 아님포함하다이러한 문자열을 포함하고 내부에 공간이 있는 디렉터리의 초기 처리를 개선할 수 있습니다( changed_abs
영향을 주지만 small_dir
나중에 수정할 사항이 더 많습니다). OP는 실제로 스크립트의 모든 관련 변수를 인용 부호로 묶어야 합니다( { }
따옴표를 바꾸지 않고).
바꾸다:
inotifywait -mr --timefmt '%m/%d/%y %H:%M' --format '%T %w %f' -e close_write /shares/Photos --includei "\.jpg|\.jpeg" | while read -r date time dir file; do changed_abs=${dir}${file} small_dir=${dir}${target}/
그리고:
inotifywait -mr --timefmt '%m/%d/%y %H:%M' --format '%T %w%f' -e close_write /shares/Photos |
grep --line-buffered -Ei '/[^/]*\.(jpg|jpeg)$' |
while read -r date time changed_abs; do
[ -d "$changed_abs" ] && continue # a directory looking like a picture filename was written to: skip this event
dir="${changed_abs%/*}/"
file="${changed_abs##*/}"
small_dir="${dir}${target}/"
아직 완전히 테스트되지는 않았지만 이것이 아이디어입니다. 디렉토리 테스트가 필요한지조차 확신할 수 없지만(이벤트가 발생하지 않는 것처럼 보임 close_write
) 문제가 되지는 않습니다.
노트
명확하지 않은 경우 감지된 각 디렉터리 생성 이벤트에 대해 작업( )을 수행
inotify_add_watch(2)
해야 합니다 .inotifywait
inotifywait
최대한 빨리다음 이벤트(경합 조건)가 누락될 수 있으므로 이 디렉터리에 새 조사식을 추가하세요. 에도 녹음되어 있어요실수부분:재귀 디렉터리에 경쟁 조건이 존재하며 관찰된 코드 [...]가 수정되지 않을 수 있습니다.
최신 버전은
inotifywait
최소 커널 5.9 이상에서 루트(또는 충분한 권한이 있는)로 실행될 때 다음을 사용할 수 있어야 합니다.fanotify(7)
inotifywait
기능이 지원되지만 충분히 새로운 커널이 지원되어야 하지만 내 버전에서 이를 사용할 수는 없었습니다 . 내가 사용할 시스템에서fanotify(7)
이--filesystem
옵션을 결합하면 각각의 새 디렉터리에 대해 이 작업을 수행할 필요가 없어지고 OP의 접근 방식이 필터링을 기반으로 작동하게 될 것이라고 가정합니다--includei
.