<>有些命令不支持输入流

前面我们讲过,有些命令是不支持输入流的,只支持命令行参数,如最常用的 ls。我们通常这样使用
$ ls /var/ backups cache crash lib local lock log mail metrics opt run snap
spool tmp
但是不能这样使用
$ echo "/var" | ls
这样使用的话,ls 会忽略管道传递给它的输入流。最终相当于,仅仅运行了不带参数的 ls。

<>xargs 的用处

那么,如果命令行或脚本确实需要用到类似的写法,有什么解决办法呢?答案就是用 xargs,xargs
的其中一个作用就是可以将管道或标准输入的数据转换成命令行参数,例如
$ echo "/var" | xargs ls backups cache crash lib local lock log mail metrics
opt run snap spool tmp
以上,加了一个 xargs ,就可以将管道的输出转换成 ls 的参数。

<>原理分析

管道本来的作用是连接 echo 的标准输出到 ls 的标准输入,加了 xargs,就相当于管道连接了 echo 的标准输出到 xargs
的标准输入,xargs 又将其标准输入的内容转换成命令的参数,传递给命令。

<>源码分析

先上源码

xargs.c
# define READ_ARGS(l, e, nmc, mc) process_stdin(l, e, nmc, mc) int xargs_main(
int argc, char **argv) { while ((list = READ_ARGS(list, eof_str, n_max_chars,
max_chars)) != NULL || /* 从标准输入读取数据作为参数列表 */ (opt & OPT_NO_EMPTY) == 0) { opt |=
OPT_NO_EMPTY; n = 0; n_chars = 0; /* allocating pointers for execvp: a*arg,
n*arg from stdin, NULL */ args = xcalloc(n + a + 1, sizeof(char *)); /* Store
the command to be executed (taken from the command line) */ for (i = 0; i < a; i
++) args[i] = argv[i]; /* (taken from stdin) */ for (cur = list; n; cur = cur->
link) { args[i++] = cur->data; n--; } if ((opt & OPT_INTERACTIVE) == 0 ||
xargs_ask_confirmation() != 0) { child_error = xargs_exec(args); /* 执行命令,其中
args 的值可能为: args[0] = "ls", args[1] = "-a" */ } /* clean up */ for (i = a; args[
i]; i++) { cur = list; list = list->link; free(cur); } free(args); if (
child_error> 0 && child_error != 123) { break; } } return child_error; }
所以,xargs 的原理就是读取标准输入,转成参数列表,借助 exec 函数,执行命令和参数。

<>提升

我们发现,通过 xargs 执行的 ls 命令,失去了颜色,那是因为在 shell 中执行的 ls,实际上执行的是 ls --color=auto,ls 是
alias 给ls --color=auto 起的别名。要想我们的输出带颜色,可以使用如下命令:

呐,颜色回来了

技术
©2019-2020 Toolsou All rights reserved,
macOS Big Sur无法完成安装 Big Sur为什么安装不了?Pandas与openpyxl库的超强结合,再见,Excel!2021-06-03一个人不是生来就要被打败的关于linux 命令“iptables -F”,不要轻易执行随机数的生成+猜数字游戏OpenCV python 模板匹配(多匹配)Python 引用cfg类型的配置文件(configparser)(telnetlib的使用方法)navicat运行sql文件时错误JVM老年代垃圾回收Full GCplc和单片机哪个更有前途?为什么本科生都不搞plc?