使用find命令加-type f参数为何返回目录?
GNU find命令参数顺序引发的筛选异常
问题经过
做代码分析时,用cat批量处理文件,出现一堆目录报错:
cat: rust/library/portable-simd/crates/test_helpers: Is a directory cat: rust/library/core/tests/iter/adapters: Is a directory cat: rust/library/core/src/iter/adapters: Is a directory cat: rust/library/test/src/formatters: Is a directory cat: rust/library/test/src/helpers: Is a directory
为了只筛选普通文件,用find加-type f,同时加-print0避免文件名含特殊字符的问题,结果却输出了目录:
$ find rust/library/core/src/iter/adapters -print0 -type f | hexdump -C | head -n3 00000000 72 75 73 74 2f 6c 69 62 72 61 72 79 2f 63 6f 72 |rust/library/cor| 00000010 65 2f 73 72 63 2f 69 74 65 72 2f 61 64 61 70 74 |e/src/iter/adapt| 00000020 65 72 73 00 72 75 73 74 2f 6c 69 62 72 61 72 79 |ers.rust/library|
第一个输出的就是目录:
$ la -d rust/library/core/src/iter/adapters/ drwxr-xr-x 2 user group 4096 Apr 11 01:57 rust/library/core/src/iter/adapters/
更奇怪的是,去掉-print0后,目录就不会被输出了:
$ find rust/library/core/src/iter/adapters -type f | hexdump -C | head -n3 00000000 72 75 73 74 2f 6c 69 62 72 61 72 79 2f 63 6f 72 |rust/library/cor| 00000010 65 2f 73 72 63 2f 69 74 65 72 2f 61 64 61 70 74 |e/src/iter/adapt| 00000020 65 72 73 2f 6d 61 70 2e 72 73 0a 72 75 73 74 2f |ers/map.rs.rust/|
一开始怀疑是find的bug,但find是久经测试的工具,后来调整参数顺序就正常了:
$ podman run --rm -i -v ".:/data" --workdir /data docker.io/cicirello/gnu-on-alpine:latest find rust/library/core/src/iter/adapters -type f -print0 | hexdump -C | head -n3 00000000 72 75 73 74 2f 6c 69 62 72 61 72 79 2f 63 6f 72 |rust/library/cor| 00000010 65 2f 73 72 63 2f 69 74 65 72 2f 61 64 61 70 74 |e/src/iter/adapt| 00000020 65 72 73 2f 6d 61 70 2e 72 73 00 72 75 73 74 2f |ers/map.rs.rust/|
容器内外用的都是find 4.9.0,结果正常。
原因分析
GNU find的参数是按顺序执行的:
- 当
-print0放在-type f前面时,find会先执行-print0输出当前路径(也就是起始目录rust/library/core/src/iter/adapters),之后才去判断-type f。这时候起始目录是目录,不符合-type f的条件,但已经被输出了。 - 省略
-print0时,find默认的行为是所有条件判断通过后才输出,所以起始目录因为不符合-type f,不会被输出。 - 把
-type f放在-print0前面,find会先筛选出所有符合条件的普通文件,再执行-print0输出,自然就不会出现目录了。
内容的提问来源于stack exchange,提问作者Banyoghurt
相关产品推荐
相关产品推荐

