在研究这个问题时:根据文件类型和日期查找并移动目录,我偶然发现了自己的一个问题。
首先,我创建了一堆包含文件的目录:
seq 10 | while read dir; do
mkdir dir$dir
touch dir$dir/file.txt
seq 5 | while read file; do
touch dir$dir/file${dir}_$file
done
done
然后我尝试了以下 find 命令:
$ find -type f -name "*.txt"
./dir6/file.txt
./dir8/file.txt
./dir10/file.txt
...
按预期工作。
现在有-exec
:
$ find -type f -name "*.txt" -exec sh -c 'echo mv -v "${0%/*}" ../bar' {} \;
mv -v ./dir6 ../bar
mv -v ./dir8 ../bar
mv -v ./dir10 ../bar
...
按预期工作。
现在实际的命令:
$ find -type f -name "*.txt" -exec sh -c 'mv -v "${0%/*}" ../bar' {} \;
`./dir6' -> `../bar/dir6'
它在第一个之后停止mv
。没有错误消息。退出状态为 0。该目录bar
存在并且dir6
已正确移动。
当我再次执行时,会发生这种情况:
$ find -type f -name "*.txt" -exec sh -c 'mv -v "${0%/*}" ../bar' {} \;
`./dir8' -> `../bar/dir8'
在第一个之后再次停止mv
。退出状态为 0。dir8
已正确移动。
为什么find
在第一个之后就停止了mv
?因为目录被移动了,find
混乱了?为什么它不打印错误或返回错误退出状态?
当我创建更多目录和更多文件时,它具有相同的行为。
在上面链接的问题中,问题是find
执行一次没有问题,但此后的所有匹配都会打印错误。这有关系吗?
使用find (GNU findutils) 4.4.2
。
答案1
在:
find -type f -name "*.txt" -exec sh -c 'mv -v "${0%/*}" ../bar' {} \;
find
打开当前目录( .
),获取内容( list1
)。然后继续处理该列表。它处理dir6
;由于该文件是一个目录,因此它会 chdirs 进入该目录,打开它并获取第二个文件列表 ( list2
),进行处理file.txt
并执行以下操作:
mv -v ./dir6 ../bar
现在,find
的当前目录没有改变,但它的路径已经改变:现在是../bar/dir6
。遍历完 的内容后dir6
,又回到了( chdir("..")
),现在处于../bar
.find
检测到目录与之前不一样并退出。