1. 首页
  2. 系统运维
  3. Linux

Linux系统xargs命令的使用

在 UNIX/Linux 系统中,xargs 这个命令和其他的命令结合之后,将会变得非常有用。这里我们整理了一些常见的 xargs 使用范例与教学,透过这些简单的范例可以很快的了解 xargs 的各种使用方法。

Linux系统xargs命令的使用

虽然这里的范例都很简单,但是当你了解 xargs 的用法之后,你会发现 xargs 其实可以拿来处理各式各样的问题,而且非常好用,尤其是对于服务器的系统管理者而言,在管理大量的文件和目录结构时,有这样的工具会方便很多。

xargs 基本用法

xargs 这个命令会从标准输入(standard input)读取资料,并以空白字符或换行作为分隔,将输入的内容切割成多个字符串,并将这些字符串当成指定命令(预设为 /bin/echo)执行时的参数。如果直接执行

xargs

接着在终端中输入

arg1 arg2
arg3

结束时按下 Ctrl + d。这时候 xargs 就会把输入的两行资料切割成 3 个字串(分别为 arg1、arg2 与 arg3),接著把这三个字符串当作指定命令的参数。而这里因为我们没有指定任何命令,所以默认就会使用 /bin/echo,结果就是直接把三个字符串输出至终端中。

arg1 arg2 arg3

这里虽然输入的内容中有包含一个换行字符(\n),不过因为 xargs 默认不会保留换行字符,所以整个输出就变成一整行。这个效果相当于

/bin/echo arg1 arg2 arg3

xargs 在读取标准输入的内容时,会自动忽略空白行,多余的空白或是 tab 字符也会被自动忽略。

如果要指定 xargs 所要执行的命令,可以直接将命令的名称放在所有 xargs 的参数之后,例如

xargs cat
arg1 arg2
arg3

就相当于

cat arg1 arg2 arg3

分隔字符

如果要指定 xargs 在读取标准输入时所使用的分隔字符,可以使用 -d 这个参数。例如:

xargs -d\n
arg1 arg2
arg3

输出为

arg1 arg2
arg3

这里我们使用 -d 这个参数指定分隔字符时,xargs 就会将换行字符保留下来,所以输出就分成了两行。

参数个数上限

默认情况下,xargs 会把从标准输入的资料所分割出来的字串,一次全部都放进指定命令参数中,例如:

echo a b c d e f | xargs

就相当于

echo a b c d e f

所以输出为

a b c d e f

如果我们不想让所有的参数都放进一个命令中执行,那么可以使用 -n 参数来指定每一次执行命令所使用的参数个数上限值,例如

echo a b c d e f | xargs -n 3

就相当于

echo a b c
echo d e f

所以输出就变为

a b c
d e f

执行前的确认

如果你对于 xargs 的使用方式不是很熟悉,或是需要以 root 权限执行一些不容出错的命令,可以加上 -p 参数,让指令在实际执行之前先进行确认的动作。例如:

echo a b c d e f | xargs -p -n 3

则在每一行命令执行前,都会先确认,如果要执行就输入 y,若不执行则输入 n。假设每一个命令我们都输入 y 让它执行,则整个输出就会变成这样:

/bin/echo a b c ?…y
/bin/echo d e f ?…a b c
y
d e f

这里因为 xargs 的确认信息与 echo 指令的输出混在一起,所以看起来有点奇怪。

如果所有的指令进行确认时,我们都输入 n,这样就不会执行任何的 echo 命令,输出就会像这样:

/bin/echo a b c ?…n
/bin/echo d e f ?…n
/bin/echo ?…n

忽略空字符串参数

大家应该有注意到上面的例子,当我们使用 -p 参数时,如果所有的命令都输入 n 跳过不执行时,最后还会出现一个没有任何参数的 echo 指令,如果想要避免以这种空字符串作为参数来执行指令,可以加上 -r 参数:

echo a b c d e f | xargs -p -n 3 -r
/bin/echo a b c ?…n
/bin/echo d e f ?…n

如果标准输入为空字符串时,xargs 默认还是会执行一次 echo 指令:

xargs -p
/bin/echo ?…n

这种状况同样可以加上 -r 参数:

xargs -p -r

显示执行的命令

使用 -t 参数可以让 xargs 在执行命令之前先显示要执行的指令,这样可以让使用者知道 xargs 执行了哪些命令。

xargs -t
abcd

按下 Ctrl + d 之后,xargs 就会先输出要执行的命令,接著才是实际执行的输出,最后得到输出为

/bin/echo abcd 
abcd

xargs 与 find 的组合命令

xargs 本身的功能并不多,但是他跟其他的 Linux 命令一起搭配使用时,功能就会显得很强大。

与 find 合在一起使用是 xargs 的一项非常重要的功能,它可以让你找寻特定的文档,并且指定需要的操作。

假设我们有一些文件夹,其中包含各式各样的文件,以 tree 命令查看目录结构会呈现

.
├── folder1
│   ├── file1.c
│   ├── file1.h
│   ├── file2.c
│   └── file2.h
└── folder2
    ├── file3.c
    └── file3.h

假设我们想要找出目前路径之下的所有 .c 文件,并且将其删除,就可以使用

find . -name "*.c" | xargs rm -f

这里我们将 xargs 要执行的命令指定为 rm -f,让 find 所找到的 .c 文件都当成 rm -f 的参数,所以这个命令的效果就相当于

rm -f ./folder2/file3.c ./folder1/file2.c ./folder1/file1.c

如果你对于命令的操作还不是很熟悉,也可以配合上面介绍的 -p 参数,在执行前确认一下

find . -name "*.c" | xargs -p rm -f

删除 .c 文件之后,以 tree 命令查看整个目录树就会变成

.
├── folder1
│   ├── file1.h
│   └── file2.h
└── folder2
    └── file3.h

这里因为是示范用的例子,所以并没有建立太多的文件与目录结构。在实际的应用上,当整个目录结构很复杂、文件又很多的时候,使用这样的方式就会非常有效率。

包含空白的文件名称

假设我们的目录中有一些文件名中包含空白字符:

touch "G T Wang.c"

在这种状况下如果用上面 find 与 xargs 的方式会无法将其删除,原因在于当我们执行

find . -name "*.c" | xargs rm -f

的时候,xargs 所产生的命令其实为

rm -f ./G T Wang.c

因为文件名包含空白,所以这会造成 rm 命令无法正确删除该文件。

这个时候我们可以将 find 加上 -print0 参数,另外将 xargs 加上 -0 参数,改成这样

find . -name "*.c" -print0 | xargs -0 rm -rf

这样即可正确处理包含空白字符的文件名称了。

命令列长度的限制

使用 –show-limits 参数可以查看系统对于命令列长度的限制,这些限制会跟 xargs 的运作情况有关,如果要处理很大量的资料时,这些限制要注意一下。

xargs --show-limits

输出为

Your environment variables take up 2022 bytes
POSIX upper limit on argument length (this system): 2093082
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2091060
Size of command buffer we are actually using: 131072
Execution of xargs will continue now, and it will try to read its input and run commands; if this is not what you wanted to happen, please type the end-of-file keystroke.
Warning: /bin/echo will be run at least once.  If you do not want that to happen, then press the interrupt keystroke. 

xargs 与 grep 的组合命令

xargs 与 grep 两个命令的组合也是一个很常见的使用方式,它可以让你找到特定文件后,再搜索文件里的内容。

假设我们要在所有的 .c 文件中找出 stdlib.h 这个字符串,就可以使用

find . -name '*.c' | xargs grep 'stdlib.h'

我直接拿 VTK 的原码来测试,输出会像这样

./CMake/TestOggTheoraSubsampling.c:#include 
./Wrapping/Tools/lex.yy.c:#include 
./Wrapping/Tools/vtkWrapPythonInit.c:#include 
./Wrapping/Tools/vtkWrapTcl.c:#include 
./Wrapping/Tools/vtkWrapTclInit.c:#include 
./Wrapping/Tools/vtkParsePreprocess.c:#include 
./Wrapping/Tools/vtkWrapText.c:#include 
./Wrapping/Tools/vtkParseData.c:#include 
./Wrapping/Tools/vtkParseHierarchy.c:#include 
./Wrapping/Tools/vtkParseMain.c:#include 

好了,这个就是xargs的基本使用,有不正确的欢迎补充。

联系我们

0574-55011290

QQ:248687950

邮件:admin@nbhao.org

工作时间:周一至周五,9:00-18:00,节假日休息

QR code