xargs命令

-- TOC --

xargs命令可以将stdin的输入,转换成某一个命令的命令行参数,这在通过管道配合其它命令执行的场景下很是必要和炫酷。

Linux命令行的管道,是将左边命令的stdout输出,作为右边命令的stdin输入;而管道右边如果是xargs命令,就可以将左边的输出,当做右边命令的命令行参数来使用!如下示例区别:

$ echo 'cs.pynote.net' > test.txt
$ echo 'test.txt' | xargs cat
cs.pynote.net
$ echo 'test.txt' | cat
test.txt

cat命令不能将stdin的输入当做参数,如果没有xargs命令的帮衬,cat命令就只能输出从stdin收到的文件名字符串。

-0,结束符

管道左边命令的输出,可能包含各种空格,tab,以及newline,这些对于xargs来说,都是分隔符。就像cpio命令一样,在处理这种复杂场景的时候,建议使用 -0 参数,对应的,管道左边的命令也要使用null来作为分隔符,这样就可以规避很多问题。比如,最常见的是如下与find命令的配合:

$ find -print0 | xargs -0 <cmd>

-I,参数占位符

-I参数用来将从stdin获取的字符串,放在xargs后面跟的命令的参数的合适位置。此参数后面跟一个replace-string:

$ find mydriver -name "*.c"
mydriver/try_write.c
mydriver/mychar.c
mydriver/eat_mem.c
mydriver/try_ioctl.c
mydriver/showcmd.c
$ find mydriver -name "*.c" | xargs -I{} cp {} a/b
$ ll a/b
total 40
drwxrwxr-x 2 xinlin xinlin  4096 2月   9 10:20 ./
drwxrwxr-x 3 xinlin xinlin  4096 2月   9 10:12 ../
-rw-rw-r-- 1 xinlin xinlin   710 2月   9 10:20 eat_mem.c
-rw-r--r-- 1 xinlin xinlin 13081 2月   9 10:20 mychar.c
-rw-rw-r-- 1 xinlin xinlin   746 2月   9 10:20 showcmd.c
-rw-rw-r-- 1 xinlin xinlin  1779 2月   9 10:20 try_ioctl.c
-rw-rw-r-- 1 xinlin xinlin   977 2月   9 10:20 try_write.c
$ rm a/b/*.c
$ find mydriver -name "*.c" | xargs -I c_file cp c_file a/b
$ ll a/b
total 40
drwxrwxr-x 2 xinlin xinlin  4096 2月   9 10:20 ./
drwxrwxr-x 3 xinlin xinlin  4096 2月   9 10:12 ../
-rw-rw-r-- 1 xinlin xinlin   710 2月   9 10:20 eat_mem.c
-rw-r--r-- 1 xinlin xinlin 13081 2月   9 10:20 mychar.c
-rw-rw-r-- 1 xinlin xinlin   746 2月   9 10:20 showcmd.c
-rw-rw-r-- 1 xinlin xinlin  1779 2月   9 10:20 try_ioctl.c
-rw-rw-r-- 1 xinlin xinlin   977 2月   9 10:20 try_write.c

上面的测试,使用了{}c_file这两个replace-string。

-p,交互

-p, --interactive

-p, --interactive Prompt the user about whether to run each command line and read a line from the terminal. Only run the command line if the response starts with y or Y. Implies -t.

小写p,让xargs后面的命令,以交互的方式运行。

-P,并发进程数

-P,大写P,此参数用来指定最大进程数,即通过xargs启动的后续命令的进程数量,让后续命令多进程运行。

-P max-procs, --max-procs=max-procs

Run up to max-procs processes at a time; the default is 1. If max-procs is 0, xargs will run as many processes as possible at a time. Use the -n option or the -L option with -P; otherwise chances are that only one exec will be done. While xargs is running, you can send its process a SIGUSR1 signal to increase the number of commands to run simultaneously, or a SIGUSR2 to decrease the number. You cannot increase it above an implemen‐ tation-defined limit (which is shown with --show-limits). You cannot decrease it below 1. xargs never terminates its com‐ mands; when asked to decrease, it merely waits for more than one existing command to terminate before starting another.

Please note that it is up to the called processes to properly manage parallel access to shared resources. For example, if more than one of them tries to print to stdout, the output will be produced in an indeterminate order (and very likely mixed up) unless the processes collaborate in some way to prevent this. Using some kind of locking scheme is one way to prevent such problems. In general, using a locking scheme will help ensure correct output but reduce performance. If you don't want to tolerate the performance difference, simply arrange for each process to produce a separate output file (or otherwise use sep‐ arate resources).

-n,参数数量

-n, number of args for cmd line

-n max-args, --max-args=max-args Use at most max-args arguments per command line. Fewer than max-args arguments will be used if the size (see the -s option) is exceeded, unless the -x option is given, in which case xargs will exit.

$ touch 1 2 3 4
$ find -type f | xargs -pn2 rm
rm ./1 ./2?...y
rm ./3 ./4?...y

-E eof-str

Set the end of file string to eof-str. If the end of file string occurs as a line of input, the rest of the input is ignored. If neither -E nor -e is used, no end of file string is used.

-e[eof-str], --eof[=eof-str]

This option is a synonym for the -E option. Use -E instead, because it is POSIX compliant while this option is not. If eof-str is omitted, there is no end of file string. If neither -E nor -e is used, no end of file string is used.

$ touch 1 2 3 4
$ find -type f | xargs -E './3' rm
$ ll
total 0
-rw-rw-r--. 1 xinlin xinlin 0 Nov 15 16:49 3
-rw-rw-r--. 1 xinlin xinlin 0 Nov 15 16:49 4

这个例子必须要先按顺序创建1234四个文件,然后再用find配合xargs命令,当遇到3号文件的时候停止,最后只剩下3和4两个文件。

xargs命令用来给其它命令准备命令行参数,当直接使用xargs的时候,可以起到规整命令行参数的作用(这里的规整,我理解就是以单空格的方式来间隔参数):

$ echo '1     3     5' | xargs
1 3 5
$ echo -e '1\n3\n5' | xargs
1 3 5

此时,再看看-n参数:

$ echo '1 2 3    4 5 6   7 8 9' | xargs -n3
1 2 3
4 5 6
7 8 9

更复杂的情况,可能需要从一个字符串中分割出命令行的参数,使用-d参数:

$ echo -n '1a2a3a4' | xargs -da
1 2 3 4

本文链接:https://cs.pynote.net/sf/linux/shell/202111152/

-- EOF --

-- MORE --