在 inotifywait 中是否考虑删除事件 close_write?
Are delete events considered close_write in 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
Cleaned-up 您的脚本并添加了引号和检查已处理文件的安全性,以防文件系统触发同一文件的重复事件。
#!/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=
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
)
我有一个简单的 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
Cleaned-up 您的脚本并添加了引号和检查已处理文件的安全性,以防文件系统触发同一文件的重复事件。
#!/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=
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
)