在研究这个问题时:Find and move directory based on file type and date,我偶然发现了我自己的一个问题。
首先,我创建了一堆包含文件的目录:
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
Run Code Online (Sandbox Code Playgroud)
然后我尝试了以下 find 命令:
$ find -type f -name "*.txt"
./dir6/file.txt
./dir8/file.txt
./dir10/file.txt
...
Run Code Online (Sandbox Code Playgroud)
按预期工作。
现在有一个-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
...
Run Code Online (Sandbox Code Playgroud)
按预期工作。
现在实际的命令:
$ find -type f -name "*.txt" -exec sh -c 'mv -v "${0%/*}" ../bar' {} \;
`./dir6' -> `../bar/dir6'
Run Code Online (Sandbox Code Playgroud)
它在第一个之后停止mv
。没有错误信息。退出状态为 0。目录bar
存在并被dir6
正确移动。
当我再次执行时,会发生这种情况:
$ find -type f -name "*.txt" -exec sh -c 'mv -v "${0%/*}" ../bar' {} \;
`./dir8' -> `../bar/dir8'
Run Code Online (Sandbox Code Playgroud)
第一次后再次停止mv
。退出状态为 0。dir8
移动正确。
为什么find
先停后mv
?是因为目录移动了,find
糊涂了?为什么它不打印错误或返回错误退出状态?
当我创建更多目录和更多文件时,它具有相同的行为。
在上面链接的问题中,问题是find
执行一次没有问题,但之后所有匹配项都会打印错误。这有关系吗?
使用find (GNU findutils) 4.4.2
.
在:
find -type f -name "*.txt" -exec sh -c 'mv -v "${0%/*}" ../bar' {} \;
Run Code Online (Sandbox Code Playgroud)
find
打开当前目录 ( .
),获取内容 ( list1
)。然后继续处理该列表。它处理dir6
; 由于该文件是一个目录,因此它会 chdirs 进入其中,打开它会获取第二个文件列表 ( list2
),处理file.txt
并执行以下操作:
mv -v ./dir6 ../bar
Run Code Online (Sandbox Code Playgroud)
现在,find
的当前目录没有改变,但它的路径已经改变:现在是../bar/dir6
. 遍历完 的内容后dir6
,返回上(chdir("..")
),现在在../bar
. find
检测到目录与之前不同并退出。