Считаются ли события удаления close_write в inotifywait?

У меня есть простой скрипт inotifywait, который отслеживает загрузку файлов FTP как закрыто, а затем перемещает их в aws s3. Вроде работает, за исключением того, что в логах inotify указано, что файл не найден (хотя файл действительно был загружен на s3). Команда s3 move перемещает файл в облако и удаляет его локально. Может ли это быть связано с тем, что inotifywait обнаруживает удаление файла как событие close_write? Почему кажется, что inotify дважды выполняет команды?

TARGET=/home/*/ftp/files

inotifywait -m -r -e close_write $TARGET |
    while read directory action file
    do
        if [[ "$file" =~ .*mp4$ ]]
        then
            echo COPY PATH IS "$directory$file"
            aws s3 mv "$directory$file" s3://bucket
        fi
    done

примеры журналов:

Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
COPY PATH IS /home/user/ftp/files/2022/05/16/user-cam-1_00_20220516114055.mp4
COPY PATH IS /home/user/ftp/files/2022/05/16/user-cam-1_00_20220516114055.mp4
COPY PATH IS /home/user/ftp/files/2022/05/16/user-cam-1_00_20220516114055.mp4
move: ../user/ftp/files/2022/05/16/user-cam-1_00_20220516114055.mp4 to s3://bucket/user-cam-1_00_20220516114055.mp4
upload: ../user/ftp/files/2022/05/16/user-cam-1_00_20220516114055.mp4 to s3://bucket/user-cam-1_00_20220516114055.mp4
move failed: ../user/ftp/files/2022/05/16/user-cam-1_00_20220516114055.mp4 to s3://bucket/user-cam-1_00_20220516114055.mp4 [Errno 2] No such file or directory: '/home/user/ftp/files/2022/05/16/user-cam-1_00_20220516114055.mp4'
rm: cannot remove '/home/user/ftp/files/2022/05/16/user-cam-1_00_20220516114055.mp4': No such file or directory
                                                                                                                  

Я не думаю, что это должно делать это. Возможно, aws s3 mv по какой-то причине открывает файл для записи.

Barmar 16.05.2022 19:56

В любом случае, вы можете добавить if [ -e "$directory$file" ], чтобы убедиться, что файл все еще существует.

Barmar 16.05.2022 19:59

вы также должны заключать в двойные кавычки свои расширения переменных

Fravadona 16.05.2022 20:20

Я попытался добавить [ -e "$directory$file" ] в мое предложение if в соответствии с вашим предложением if [ -e "$directory$file" ] && [[ "$file" =~ .*mp4$ ]], но я вижу такое же поведение. Я включил некоторые журналы выше. Я понятия не имею, почему это происходит.

ninsonTan 16.05.2022 21:14

также это, вероятно, не из-за aws s3 mv открытия файла, потому что даже простая команда unix cp приводит к той же ошибке.

ninsonTan 16.05.2022 22:19
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
31
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Очистил ваш скрипт и добавил некоторую безопасность с кавычками и проверкой уже обработанного файла на случай, если файловая система инициирует повторяющиеся события для одного и того же файла.

#!/usr/bin/env bash

# Prevents expanding pattern without matches
shopt -s nullglob

# Expands pattern into an array
target=(/home/*/ftp/files/)

# Creates temporary directory and cleanup trap
declare -- tmpdir=
if tmpdir=$(mktemp -d); then
  trap 'rm -fr -- "$tmpdir"' EXIT INT
else
  # or exit error if it fails
  exit 1
fi

# In case no target matches, exit error
[ "${#target[@]}" -gt 0 ] || exit 1

s3move() {
  local -- p=$1
  local -- tmp = "$tmpdir/$p"
  printf 'Copy path is: %s\n' "$p"
  # Moves the file to temporary dir
  # so it is away from inotify watch dir ASAP
  mv -- "$p" "$tmp"

  # Then perform the slow remote copy to s3 bucket
  # Remove the echo onces it is ok
  echo aws s3 mv "$p" s3://bucket
  
  # File has been copied to s3, tmp file no longer needed
  rm -f -- "$tmp"
}

while read -r -d '' p; do
  # Skip if file does not exist, as it has already been moved away
  # case of a duplicate event for already processed file
  [ -e "$p" ] || continue
  s3move "$p"
done < <(
  # Good practice to spell long option names in a script
  # --format will print null-delimited full file path
  inotifywait \
    --monitor \
    --recursive \
    --event close_write \
    --includei '.*\.mp4$' \
    --format '%w%f%0' \
    "${target[@]}" 2>/dev/null
)

Другие вопросы по теме