这是一个小问题,但有点烦人。我看了又看,但我不太明白为什么会发生这种情况或如何阻止它。我有数千个视频文件,出于多种原因,我正在慢慢地将它们从 MPEG II 格式转换为 MP4 容器中的 h.264。每个.mpg文件都有一个与之关联的.txt文件和.jpg文件,这些文件需要从“xxxxxxxxxxxxxxx.mpg.txt和xxxxxxxxxxxxxxx.mpg.jpg更改为xxxxxxxxxxxxxxx.mp4.txt和xxxxxxxxxxxxxx.mp4.jpg”分别,然后需要删除旧的 .mpg 文件,我使用以下名为 mpgscan.sh 的脚本来执行此操作:
#! /bin/bash
suffix=".mpg"
mpegname="$@"
filename=${mpegname%"$suffix"}
mp4name="$filename"".mp4"
if [ -s "$mp4name" ]
then
if lsof "$mp4name" > /dev/null || lsof "$mpegname" > /dev/null
then
echo "$filename in use"
else
if [[ -f "$mpegname"".txt" ]]
then
rename -f 's/\.mpg.txt$/.mp4.txt/' "$mpegname"".txt"
fi
if [[ -f "$mpegname"".jpg" ]]
then
rename -f 's/\.mpg.jpg$/.mp4.jpg/' "$mpegname"".jpg"
fi
echo "$filename removed"
rm "$mpegname"
fi
fi
文件的转换是在后台进行的,因此每隔一段时间我就会通过输入以下命令来批量更新关联的文件:
find /RAID/Recordings -name "*.mpg" -exec mpegscan.sh {} \;
它工作得很好,但没有得到像这样的预期输出:
/RAID/Recordings/Movies/K/K-9 (Recorded Tue Apr 01, 2008, HBOHD) removed
/RAID/Recordings/Movies/K/Kate & Leopold (Recorded Sat Sep 11, 2010, ENCR1H) removed
/RAID/Recordings/Movies/K/Kindergarten Cop (Recorded Tue May 06, 2008, HBOHD) removed
/RAID/Recordings/Movies/K/King Ralph (Recorded Wed Jul 16, 2008, HBOHD) in use
我得到:
/RAID/Recordings/Movies/K/K-9 (Recorded Tue Apr 01, 2008, HBOHD) removed
find: '/RAID/Recordings/Movies/K/K-9 (Recorded Tue Apr 01, 2008, HBOHD).mpg.jpg': No such file or directory
find: '/RAID/Recordings/Movies/K/K-9 (Recorded Tue Apr 01, 2008, HBOHD).mpg.txt': No such file or directory
/RAID/Recordings/Movies/K/Kate & Leopold (Recorded Sat Sep 11, 2010, ENCR1H) removed
find: '/RAID/Recordings/Movies/K/Kate & Leopold (Recorded Sat Sep 11, 2010, ENCR1H).mpg.jpg': No such file or directory
find: '/RAID/Recordings/Movies/K/Kate & Leopold (Recorded Sat Sep 11, 2010, ENCR1H).mpg.txt': No such file or directory
/RAID/Recordings/Movies/K/Kindergarten Cop (Recorded Tue May 06, 2008, HBOHD) removed
find: '/RAID/Recordings/Movies/K/Kindergarten Cop (Recorded Tue May 06, 2008, HBOHD).mpg.jpg': No such file or directory
find: '/RAID/Recordings/Movies/K/Kindergarten Cop (Recorded Tue May 06, 2008, HBOHD).mpg.txt': No such file or directory
/RAID/Recordings/Movies/K/King Ralph (Recorded Wed Jul 16, 2008, HBOHD) in use
我已经尝试了rename
和mv
命令,但结果相同。我很困惑。首先,命令如何/为什么报告错误find
? find 命令不是针对 .jpg 或 .txt 文件发出的,而是针对 .mpg 文件发出的。更重要的是,为什么会出现任何错误?报告的文件确实存在,并且 mv / rename 命令正在正确处理它们。不仅如此,我什至在重命名它们之前检查脚本以确保它们确实存在。我缺少什么?如果我针对任何 .mpg 文件手动运行该脚本,该脚本将完美运行,不会出现任何错误。
答案1
find
读取目录条目列表并逐一处理它们。对于与您的条件匹配的每个条目,它-exec
都会使用您的 shell 脚本。
find
然后,您的脚本会重命名文件,从而更改仍在处理的目录条目列表。因此,find
其待办事项列表中仍然有您已删除/重命名的文件名。
当find
尝试处理它们时,它会抱怨该文件不再存在。
例子:
# create files in random order
$ shuf -e {a..z} {a..z}.foo {a..z}.bar | xargs touch
# rename using find -exec mv
$ busybox find -name "[a-z]" -exec mv {}.foo {}.baz \;
find: ./i.foo: No such file or directory
find: ./t.foo: No such file or directory
find: ./d.foo: No such file or directory
...
我在这里使用是busybox find
因为 GNU findutilsfind
已经足够智能来处理这种情况。您可能正在使用旧版本,甚至是 busybox 变体(如果这是某种 NAS 上的嵌入式 shell)。
如果丢失的文件无论如何都会被您的条件忽略,您可以忽略此错误;或者,让 find 首先构建文件列表,然后再处理该列表。
有时使用find -print0 | xargs -0
模式代替find -exec
模式就足够了。如果您的 shell 脚本可以处理多个参数而不是仅处理一个参数,这会有所帮助。