DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

xargs -I 后 du 找不到已有文件:文件名前面的空格被丢掉

带前导空格的文件经 xargs -I 后报 No such file or directory 时,检查名称是否在输入解析阶段被改写,再用 NUL 分隔和 GNU du 单次统计保留路径及总计。

带前导空格的文件,单独用带引号的路径交给 du 可以读取,通过 xargs -I 处理时却报 No such file or directory,而报错路径少了开头的空格。应先检查输入名称在传给 du 之前是否已经被改写。

xargs -I 按行处理输入时,会忽略行首未被引用或转义的空白。给命令里的占位符加引号,不能找回已经在输入解析阶段丢掉的字符。下面这种统计方式就可能出现问题:

ls *.mkv | xargs -I '{}' du -h '{}'

这里只说明失败结构,不建议执行后继续给名称补空格或引号。文件名中还可能有换行、反斜线和其他空白,修补一类字符并不能让 ls 输出成为可靠的文件名输入。

检查的是同一个文件名吗

对照能成功的单个路径与错误中实际使用的路径,检查是否少了前导空格、出现了额外的双引号,或者目录前缀已经不同。它们对应的解析阶段并不一样:名称少字符时,应检查输入分隔和解析;多出字面引号时,应检查调用命令的引用方式。

随后核对当前目录和选择范围。相对文件名从哪个工作目录解释、哪些文件被 glob 匹配,以及文件是否在统计过程中移动,都会影响结果。不能因为文件管理器仍显示一个相似名称,就假定 du 收到的路径与它完全相同。

ls 的显示还可能受别名、颜色及引用样式影响。关闭颜色只能消除显示修饰,不会解决 -I 的行首空白规则,也不能避免文件名本身带换行造成的歧义。

GNU du 可以直接读取 NUL 分隔的名称

若目标是在 GNU/Linux 上统计一个目录第一层普通 .mkv 文件的磁盘占用,可让 find 用 NUL 分隔名称,再让 GNU du 直接读入:

find /srv/media -mindepth 1 -maxdepth 1 -type f   -name '*.mkv' ! -name '.*' -print0 |
  du --files0-from=- -ch

/srv/media 是示例目录,需换成真正的统计目标。-maxdepth 1 限制到当前目录第一层,-type f 只选普通文件,示例排除隐藏名称,也不跟随符号链接。若原业务要统计子目录、隐藏文件或链接,应先明确选择规则再调整,不能把数量差异全归给参数解析。

'*.mkv' 要由 find 匹配,单引号防止 shell 提前把它展开成一串文件参数。-print0 输出真实名称并以 NUL 分隔;--files0-from=- 从标准输入读取同样的分隔格式,不再经过 xargs -I 的文本行解析。这样可以保留前导空格及文件名内的换行。

不要把原来的 ls 输出经 tr 改成 NUL,便当作安全输入。输出里的换行可能已经无法区分“文件名中的字符”与“两个文件之间的分隔”;必须从产生文件名称的阶段使用无歧义的分隔方式。

这里使用 GNU find 与 GNU du 扩展。系统的其他实现可能没有 --files0-from 或相同的深度选项,应核对实际工具,不直接把命令搬到所有 Unix 环境。

总计也应来自同一次统计

-h 以便于阅读的单位显示占用,-c 在同一次 du 调用中给出总计。若改成 xargs 分批启动多个 du -c,各批输出的是自己的小计,最后一批不能代表全部文件。单次 --files0-from 也避免把大量名称塞进命令行参数。

du 默认统计磁盘占用,并非文件的逻辑长度;稀疏文件、压缩文件系统等情况下,两者可以不同。硬链接默认也有去重计数规则。不要把已经四舍五入并带 K、M、G 单位的 du -h 输出直接用 awk 当作普通数字累加,否则可能再引入单位和精度错误。

没有报错,还要核对选择范围

确认那些带前导空格的目标也出现在本轮结果中,选择数量及目录范围符合预期,且 find 和 du 都没有失败。管道最后一个命令的退出状态不能单独证明上游成功;脚本应按所用 shell 的管道状态规则检查两端,不在 find 报权限错误后仍接受一个看似正常的总计。

这组命令只读取目录与文件元数据,不删除或重命名文件。统计期间文件仍可能变化,结果不是固定时点的快照;需要稳定报表时,应选可控窗口或既有快照方案。调整筛选规则时保留原脚本,核对样本后再替换自动任务,不为了让错误消失而改动业务文件名。