【问题标题】:Files with quotes, spaces causing bad behavior from xargs带引号的文件,空格导致 xargs 的不良行为
【发布时间】:2017-07-13 04:40:25
【问题描述】:

我想find一些文件并使用管道命令计算shasum

find . -type f | xargs shasum

但是我的目录中有带引号的文件,例如名为

的文件
file with "special" characters.txt

管道输出如下所示:

user@home ~ $ find . -type f | xargs shasum
da39a3ee5e6b4b0d3255bfef95601890afd80709  ./empty1.txt
da39a3ee5e6b4b0d3255bfef95601890afd80709  ./empty2.txt
da39a3ee5e6b4b0d3255bfef95601890afd80709  ./empty3.txt
shasum: ./file: 
shasum: with: No such file or directory
shasum: special: No such file or directory
shasum: characters.txt: No such file or directory
25ea78ccd362e1903c4a10201092edeb83912d78  ./file1.txt
25ea78ccd362e1903c4a10201092edeb83912d78  ./file2.txt

文件名中的引号会产生问题。

如何告诉shasum 正确处理文件?

【问题讨论】:

  • 您确定需要xargs 吗? find . -type f -exec shasum {} \;
  • @chepner, ...好吧,使用-exec ... \;xargs 可以提高性能,因为我们能够启动更少的shasum 实例。也就是说,由于-exec ... {} + 可用,是的,没什么意义。
  • 在这里,我很确定启动 shasum 的开销与实际计算单个文件的校验和的成本相比可以忽略不计。
  • 如果文件很大(“不是很小”?),当然。

标签: bash shell sh xargs


【解决方案1】:

简短的解释是,xargs 被广泛认为是被设计破坏的,除非使用标准的扩展来禁用其尝试解析和尊重引用以及在其输入中转义内容的行为.详情请见the xargs section of UsingFind


使用 NUL 分隔流

在具有 GNU 或现代 BSD 扩展(包括 MacOS X)的系统上,您可以(并且应该)以 NUL 分隔 find 的输出:

find . -type f -print0 | xargs -0 shasum --

使用find -exec

也就是说,您可以通过完全符合现代(~2006)POSIX 的方式让xargs 完全脱离循环,从而做得更好:

find . -type f -exec shasum -- '{}' +

请注意,-- 参数向 shasum 指定所有未来的参数都是文件名。如果您使用了find * -type f ...,那么您可能会得到一个以破折号开头的结果;使用-- 可确保此结果不会被解释为一组选项。


使用换行符(及其安全风险)

如果您有 GNU xargs,但 没有 可以选择 NUL 分隔的输入流,那么 xargs -d $'\n'(在带有 ksh 扩展名的 shell 中)将避免引用和逃避行为:

xargs -d $'\n' shasum -- <files.txt

但是,这是次优的,因为换行文字实际上可以在文件名中使用,因此无法区分分隔两个名称的换行符和作为实际名称一部分的换行符。考虑以下场景:

mkdir -p ./file.txt$'\n'/etc/passwd$'\n'/
touch ./file.txt$'\n'/etc/passwd$'\n'file.txt file.txt
find . -type f | xargs -d $'\n' shasum --

这将产生类似于以下的输出:

da39a3ee5e6b4b0d3255bfef95601890afd80709  ./file.txt
da39a3ee5e6b4b0d3255bfef95601890afd80709  ./file.txt
c0c71bac843a3ec7233e99e123888beb6da8fbcf  /etc/passwd
da39a3ee5e6b4b0d3255bfef95601890afd80709  file.txt

...因此允许可以控制文件名的攻击者对要添加到您的输出的预期目录结构之外的任意文件进行 shasum。

【讨论】:

    猜你喜欢
    • 2022-01-18
    • 2021-11-30
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-02
    相关资源
    最近更新 更多