Scroll to navigation

XARGS(1) General Commands Manual XARGS(1)

名称

xargs - 从标准输入构建并执行命令行

概述

xargs [选项] [命令 [初始参数]]

描述

本手册页记载了 GNU 版本的 xargsxargs 从标准输入读取由空白字符或换行符分隔的条目(如需在条目中保留空格,可以使用单引号、双引号或者反斜线转义),并且使用给出的 初始参数 以及后续从标准输入读取的条目作为参数来执行给定的 命令(默认执行 echo)一次或多次。标准输入中的空行将被忽略。

程序持续构建给定 命令 的命令行直到遇到了系统定义的限制为止(除非使用了 -n-L 选项)。指定的 命令 会被调用多次,直到用尽输入条目列表项为止。通常情况下,调用 命令 的次数要远少于输入条目项的数量。这通常可以带来十分显著的性能提升。某些命令也可并行执行;请参见 -P选项。

因 Unix 文件名可包含空白和换行符,这样的默认行为通常会出现问题;含有空白和/或换行符的文件名无法被 xargs 正确处理。在这些场景下,最好应使用 -0 选项来避免这样的问题。使用该选项时,您应确保生成 xargs 的输入的程序同样使用空字符作为分隔符。例如如果使用了 GNU find,则应当选用其 -print0 选项。

如果任何对命令的调用返回了 255 状态码,xargs 会立刻停止而不再读取更多的输入数据。该情况发生时程序会在标准错误打印错误信息。

选项

-0, --null
输入条目以空字符结束,而不是以空白结束,引号和反斜杠也不特殊(每个字符都按字面意思理解)。禁用文件结束字符串(EOF),该字符串与其他参数按相同方法处理。当输入项可能包含空白、引号或反斜线时,该选项非常有用。GNU find -print0 选项产生的输入适合这种模式。

从给定file而不是标准输入读取条目。如果使用该选项,运行命令时标准输入将保持不变。否则,标准输入将从 /dev/null 重定向。

输入条目由指定字符分隔而结束。所指定的分隔符可能是单个字符、类似 \n 的 C 风格字符转义序列、或者八进制/十六进制转义代码。八进制和十六进制转义代码和 printf 命令所使用的格式一致。不支持多字节字符。处理输入时,引号和反斜线并不会被特殊处理;输入中的每个字符都被按照其字面样式进行处理。使用 -d 选项会禁用所有文件结束字符串,令其与其它参数按照相同方式处理。在输入仅包含用换行符分隔的条目时可以使用该选项;但如果可能的话,设计让程序使用 --null 选项几乎总是更好的方案。

将文件结束字符串设置为 eof-str。如果该文件结束字符串作为一行输入出现,则其后的输入内容均会被忽略。如果既未使用 -E 也未使用 -e,则不使用任何文件结束字符串。
该选项是 -E 选项的同义词。请使用 -E ,因为它符合 POSIX 标准,而该选项不符合 POSIX 标准。如果省略 eof-str ,则没有文件结束字符串。如果既没有使用 -E 也没有使用 -e,则不会使用文件结尾字符串。
将给定初始参数中出现的替换占位字符串替换为从标准输入中读取得到的字符串。另外,未被引号包括的空白字符不会被视为输入项目的分隔符;此时分隔符是换行符。该选项隐含启用了 -x-L 1 选项。
如果给出了替换占位字符串,则该选项和 -I替换占位字符串同义。如果缺失了替换占位字符串,则其效果等同于 -I{}。-i 已被弃用,请改用 -I
每个命令行使用至多最大行数个非空输入行。行末尾的空白字符会使得下一行成为上一行逻辑上的延续。隐含启用 -x
-L 选项同义。但与 -L 不同,此时最大行数的参数是可选的。如果未指定最大行数,则默认取值为 1。-l 选项已被弃用,因为 POSIX 标准指定了使用 -L 选项。
每条命令行最多使用 max-args 个参数。如果参数总大小超过限制(参见 -s 选项),则实际使用的参数数量可能少于 max-args,除非指定了 -x 选项;在这种情况下,xargs 将直接退出。
同时最多运行 max-procs 个进程;默认值为 1。如果 max-procs 为 0,则 xargs 会尽可能多地同时运行进程。应当配合 -n 选项或 -L 选项与 -P 一起使用;否则很可能只执行一次 exec。在 xargs 运行期间,你可以向其进程发送 SIGUSR1 信号来增加并行运行的命令数,或发送 SIGUSR2 信号来减少该数量。增加数量时不能超过实现定义的上限(可通过 --show-limits 查看),减少数量时不能低于 1。xargs 永远不会主动终止其启动的命令;当请求减少并发数时,它只会在已有的多个命令终止之后才启动新的。xargs 在退出前总是会等待所有子进程结束(但有例外,请参见本文档“缺陷”一节)。

如果未使用 -P 选项,xargs 将不会处理 SIGUSR1 和 SIGUSR2 信号,这意味着这些信号将会终止该程序(除非在启动 xargs 之前,这些信号已在父进程中被屏蔽)。

请注意,被调用的进程需自行负责正确管理对共享资源的并发访问。例如,如果多个进程同时尝试向标准输出打印内容,除非它们以某种方式进行协作防止冲突,否则输出的顺序将无法确定(并且很可能会混杂在一起)。采用某种锁机制是一种防止此类问题的方法。一般而言,使用锁机制有助于确保输出正确,但会降低性能。如果你不希望承受性能差异的影响,可以让每个进程输出到不同的文件,或者以其他方式使用不同的资源。

在执行命令之前,在子进程中将标准输入重新打开为 /dev/tty。如果你希望 xargs 运行一个交互式应用程序,这将非常有用。
在执行每条命令行之前提示用户确认,并从终端读取一行输入。仅当用户的响应以“y”或“Y”开头时才执行该命令行。此选项隐含启用 -t
将环境变量 name 设置为每个正在运行的子进程中的唯一值。一旦子进程退出,该值会被重新使用。例如,这可以用于实现一个基本的负载分配方案。
如果标准输入中不包含任何非空白字符,则不执行命令。通常情况下,即使没有输入,命令也会执行一次。此选项是 GNU 扩展功能。
每条命令行最多使用 max-chars 个字符,包括命令本身、初始参数以及每个参数字符串末尾的空字符。最大允许值依赖于系统,其计算方式为:exec 的参数长度限制,减去环境变量所占空间,再减去 2048 字节的保留空间。如果计算出的值超过 128 KiB,则默认值为 128 KiB;否则,默认值为该最大值。其中 1 KiB 等于 1024 字节。xargs 会自动适应更严格的限制。
显示操作系统施加的命令行长度限制、xargs 所选择的缓冲区大小,以及 -s 选项所设定的限制。如果你不希望 xargs 实际执行任何操作,可以将输入通过管道重定向为来自 /dev/null(并可考虑加上 --no-run-if-empty 选项)。
在执行命令之前,将该命令行打印到标准错误输出上。
如果大小超出限制(参见 -s 选项),则退出程序。
--
用于标记选项列表的结束。其后的参数(如果有)即使以 - 开头,也会被当作操作数处理。例如,xargs -- --help 会运行 PATH 中名为 --help 的命令,而不是打印用法说明;xargs -- --mycommand 会执行命令 --mycommand,而不会将其视为无法识别的选项而报错。
打印 xargs 的选项摘要并退出。
打印 xargs 的版本号并退出。

选项 --max-lines-L-l)、--replace-I-i)以及 --max-args-n)是互斥的。如果同时指定了其中多个选项,xargs 通常会采用命令行中最后指定的选项,也就是说,之前指定的冲突选项会被重置为默认值。此外,xargs 会在 stderr 上发出警告信息。此规则有一个例外:当使用 --replace 或其别名 -I-i 后,若再次指定特殊值 1(即 '-n1'),该值将被忽略,因为它实际上并不构成冲突。

示例

find /tmp -name core -type f -print | xargs /bin/rm -f

/tmp 目录中或其子目录下查找名为 core 的文件并将其删除。请注意,如果有任何文件名中包含换行符或空格,该操作可能无法正确执行。

find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f

/tmp 目录中或其子目录下查找名为 core 的文件并将其删除,处理文件名时会正确处理包含空格或换行符的文件或目录名称。

find /tmp -depth -name core -type f -delete

/tmp 目录中或其子目录下查找名为 core 的文件并将其删除,且比前一个示例更高效(因为我们避免了使用 fork(2)exec(2) 来启动 rm,也不需要额外的 xargs 进程)。

cut -d: -f1 < /etc/passwd | sort | xargs echo
生成系统上所有用户的简洁列表。

退出状态

xargs 退出时会使用下列状态码:

0
表示运行成功
123
表示所调用的命令中出现了退出状态码在 1–125 范围内的情况
124
表示命令以 255 退出
125
表示命令被信号杀死
126
表示无法运行命令
127
表示命令未找到
1
表示出现了其他错误。

大于 128 的退出状态码通常由 shell 所使用,指示程序由于某个致命信号而停止。

遵循标准

截至 GNU xargs 第 4.2.9 版,xargs 的默认行为是不适用逻辑上的文件结束标记。POSIX (IEEE Std 1003.1, 2004 版) 允许该行为。

-l 和 -i 选项在 POSIX 标准的 1997 版出现,但在 2004 版中未出现。因此最好应使用 -L 和 -I 进行替代。

-o 选项是 POSIX 标准中为了加强与 BSD 的兼容性而出现的扩展。

POSIX 标准允许具体实现设置 exec 函数的参数大小限制。包含环境在内,其限制最小可以低至 4096 字节。如需编写可移植脚本,脚本不能假定更大的限制值。然而,笔者至今未曾见到最大值限制如此低的实现版本。可以使用 --show-limits 选项检查当前系统上生效的实际限制值。

xargs 4.9.0 版和之前版本中,即便未使用 -P 选项,SIGUSR1 和 SIGUSR2 也不会导致 xargs 终止运行。

历史

xargs 程序由贝尔实验室的 Herb Gellis 所发明。请参见 findutils 的 texinfo 手册中 Finding Files 一节以了解更多信息。

缺陷

无法保证 xargs 能够完全安全地运行,因为在产生输入文件的列表和其被 xargs 执行的命令所处理这两个事件之间总有时间差。如果有其他用户同时在访问系统,他们可以在这个时间窗口内操作文件系统并迫使 xargs 要运行的命令本来要处理的文件和实际处理的文件不相同。如需了解对这个问题和相关问题更详细的讨论,请参考 findutils Texinfo 文档中的“Security Considerations”章节。find 工具的 -execdir 选项通常可以被用来提供更为安全的功能替代。

在使用 -I 选项时,从输入读取的每一行都会存储在内部缓冲区。这意味着使用 -I 选项时 xargs 能接受的输入行数存在上限。如需绕过这个限制,可以使用 -s 选项来加大 xargs 所使用的缓冲区大小,且另外也可以使用多次额外的 xargs 调用来确保不会出现超长的行。例如:

某些命令 | xargs -s 50000 echo | xargs -I '{}' -s 100000 rm '{}'

在这里,第一次调用的 xargs 因为未使用 -i 选项而没有输入行长度限制。第二次调用的 xargs 确实存在限制,但我们已确保了它永远不会遇到超出其处理能力范围的行。这并不是最理想的解决方法。理想情况下,-i 选项不应该预设行长度限制,这也是本段讨论会出现在“缺陷”一节中的原因。这个问题在处理 find(1) 的输出时并不会出现,因其每行只会输出一个文件名。

xargs 4.9.0 版本及之前的版本中,xargs -P 在其子进程仍在运行,但其中某些已经返回 255 的情况下会退出。

报告缺陷

GNU findutils 在线帮助:<https://www.gnu.org/software/findutils/#get-help>
请向 <https://translationproject.org/team/zh_CN.html> 报告翻译错误。

请使用 GNU Savannah 缺陷追踪系统上的表格报告任何出现的问题:

有关 GNU findutils 软件包的通用主题可以在 bug-findutils 邮件列表上讨论:

版权

版权所有 © 1990–2024 自由软件基金会。许可证 GPLv3+:GNU GPL 第 3 版或更新版本 <https://gnu.org/licenses/gpl.html>。
这是自由软件:您可以自由地更改并对其重新发布。在法律所允许的范围内不含任何担保。

参见

find(1), kill(1), locate(1), updatedb(1), fork(2), execvp(3), locatedb(5), signal(7)

完整文档 <https://www.gnu.org/software/findutils/xargs>
或者在本地使用:info xargs

本页面中文版由中文 man 手册页计划提供。
中文 man 手册页计划:https://github.com/man-pages-zh/manpages-zh