我们可以利用管道将一个命令的stdout(标准输出)重定向到另一个命令的stdin(标准输入)。有些命令只能以命令行参数的形式接受数据,而无法通过stdin接受数据流。这时候就没法使用管道。那么xargs擅长将标准输入数据转换成命令行参数。xargs能够处理stdin并将其转换为特定命令的命令行参数。它也可以将单行或多行文本输入转换成其他格式。

1、xargs命令应该紧跟在管道操作符之后,以标准输入作为主要的源数据流。如command | xargs

2、xargs命令把从stdin接受到 的数据重新格式化,再将其作为参数提供给其他命令。xargs其作用类似于find命令中的exec。

a、将多行输入转换成单行输出。只需要将换行符移除,再用“ ”(空格)进行代替,就可以实现多行输入的转换。'\n'被解释成一个换行符,它其实就是多行文本之间的定界符。

eg:$cat example.txt

1 2 3 4 5 6

7 8 9 10

11 12

$ cat example.txt | xargs

1 2 3 4 5 6 7 8 9 10 11 12

b、将单行输入转换成多行输出。

指定每行最大的参数数量n,可以将任何来自stdin的文本划分成多行,每行n个参数。每个参数都是由“ ”(空格)隔开的字符串。空格是默认的定界符。

eg:$cat example.txt | xargs -n 3

1 2 3

4 5 6

7 8 9

10 11 12

3、工作原理

a、可以用自己的定界符来分隔参数。用-d选项为输入指定一个定制的定界符。

eg:$echo "splitXsplitXsplitXsplit" | xargs - d X

split split split split

b、结合-n选项,可以将输入划分成多行,而每行包含两个参数:

eg:$echo "splitXsplitXsplitXsplit" | xargs - d X -n 2

split split

split split

4、补充内容

1)、读取stdin,将格式化参数传递给命令

先编写一个小型的定制版echo来更好地理解用xargs提供命令行参数的方法:

#!/bin/bash

#文件名:cecho.sh

echo $* '#'

当参数传递给文件cecho.sh后,它会将这些参数打印出来,并以#字符作为结尾。如

$ ./cecho.sh arg1 arg2

arg1 arg2 #

a、有一个名为args.txt的参数列表文件,如下

$ cat args.txt

arg1

arg2

arg3

可以将这个命令执行多次,每次使用一个参数:

$ cat args.txt | xargs -n 1 ./cecho.sh

arg1 #

arg2 #

arg3 #

每次执行需要X个参数的命令时,使用:

INPUT | xargs -n X

如:

$ cat args.txt | xargs -n 2 ./cecho.sh

arg1 arg2 #

arg3 #

为了在执行命令时一次性提供所有的参数,可以使用:

$cat args.txt | xargs ./ cecho.sh

arg1 arg2 arg3 #

上面例子中,直接为特定的命令(cecho.sh)提供命令行参数。这些参数都源于args.txt文件。但实际上除了以上之外,还需要一些固定不变的命令参数。如

./cecho.sh -p arg1 -1

其中arg1是唯一的可变内容,其余部分都保持不变。我们可以从文件(args.txt)中读取参数,并按照下面的方式提供给命令:

./cecho.sh -p arg1 -1

./cecho.sh -p arg2 -1

./cecho.sh -p arg3 -1

xargs有一个-I选项,可以提供上面这种形式的命令执行序列。可以使用-I指定替换字符串,这个字符串在xarg扩展时会被替换掉。如果将-I与xargs结合使用,对于每一个参数,命令都会被执行一次。如

$cat args.txt | xargs -I {} ./cecho.sh -p {} -1

-p arg1 -1 #

-p arg2 -1 #

-p arg3 -1 #

-I {}指定了字符串。对于每一个命令参数,字符串{}都会被从stdin读取到的参数替换掉。

注意:使用-I的时候,命令以循环的方式执行。如果有3个参数,那么命令就会连同{}一起被执行3次。

2)结合find使用xargs

危险使用:

$find . -type f -name "*.txt" -print | xargs rm -f

这样做很危险,有可能删除不必要的文件。我们没法预测分隔find命令输出结果的定界符究竟是什么('\n'或者' ').有些文件名中包含空格符,因此xargs很可能会误认为是定界符(hell text.txt会被xargs误解为hell和text.txt)。

只要我们把find的输出作为xargs的输出作为xargs的输入,就必须将-print0与find结合使用,以字符null(‘\0’)来分隔输出。

用find匹配并列出所有的.txt文件,然后用xargs将这些文件删除:

$find . -type f -name "*.txt" -print0 |xargs -0 rm -f

这样就可以删除所有的.txt文件。xargs -0 将\0作为输入定界符。

3)统计源代码目录中所有c程序文件的行数

统计所有c程序文件的行数(Lines of Code,LOC)。

$find source_code_dir_path -type f -name "*.c" -print0 | xargs -0 wc -1

注意:有关个人源代码更多的统计信息,有个叫做SLOCCount的工具。

d)结合stdin,巧妙运用while语句和子shell

xargs只能以有限的几种方式来提供参数,而且它也不能为多组命令提供参数。要执行包含来自标准输入的多个参数的命令,使用如下:包含while循环的子shell可以用来读取参数,然后通过一种巧妙的方式执行命令:

$cat files.txt | (while read arg; do cat $arg;done)

#等同于cat files.txt | xargs -I {} cat {}

在while循环中,可以将cat $arg替换成任意数量的命令,这样我们就可以对同一个参数执行多条命令。也可以不借助管道,将输出传递给其他命令。这个技巧能够适用于各种问题场景。子shell操作符内部的多个命令可以作为一个整体来运行。

$cmd0 | (cmd1;cmd2;cmd3) |cmd4

如果cmd1时cd /,那么就会改变子shell工作目录,然而这种改变仅局限于子shell内部。cmd4则完全不知道工作目录发生了变化。


父Shell与子Shell

Login Shell

登录主机后,在执行Bash Script之前,其实我们已经处于一个BashShell中。

这个Shell叫login Shell,是将来我们执行任何Script的上层环境。又叫父SHell

其实每个帐号都可以自定义loginShell。以Linux来说,帐号的login Shell定义在/etc/passwd这个文件中。

/etc/passwd的每一行代表一个帐号,共有7个字段,之间用:隔开。

帐号:x:UID 使用者代码:GID 群组代码:用户信息:主目录:login shell路径

第二栏x为密码栏,基于系统安全考虑,编码后的密码已经被放入/etc/passwd文件中。

login Shell定义在第7个字段,如果这个字段的Shell程序不存在、不合法,或执行失败,则无法登录主机。

父Shell、子Shell

当在执行一个Shell Script时,父Shell会根据Script程序的第一行#!之后指定的Shell程序开启一个子Shell环境,然后在子Shell中执行此Shell Script。一旦子Shell中的Script执行完毕,此子Shell随即结束,回到父Shell中,不会影响父Shell原本的环境。

子Shell环境拥有与父Shell相同的环境变量、标准输入、输出、错误等。

例如:

test.sh文件内容

#!/bin/bash

cd /var/www/html

命令行:chmod +x /test.sh

命令行:./test.sh

执行完脚本后还原到父Shell,并且父Shell并没有进入/var/www/html目录。

注:这是因为当执行Shell文件时,父Shell会创建子Shell,各自独立。

如果需要使用父Shell来执行此脚本,可以使用:

命令行:. ./test.sh

注意.与./之间有一个空格符

子Shell继续开启子Shell

与父Shell启动子Shell方式一样,继续调用下去,即子Shell开启子Shell。

通过$SHLVL变量,可以知道当前所在Shell的层次

2.5玩转xargs的更多相关文章

  1. 玩转xargs

    xargs命令可以把标准输入数据转换成命令行参数.也可以将单行或多行文本输入转换成其他格式,是构建单行命令的重要组件之一. xargs命令应该紧跟在管道操作符之后,以stdin作为主要的源数据流,使用 ...

  2. LinuxShell脚本攻略--第二章 命令之乐

    用 cat 进行拼接 文件查找与文件列表玩转 xargs 用 tr 进行转换排序临时文件命名与随机数分割文件和数据根据扩展名切分文件名mv 批量重命名文件交互输入自动化 cat: echo 'Text ...

  3. Shell-2-命令之乐

    1.cat (1)基本用法 [root@cai tmp]# cat 1.txt 2.txt this is a test1 this is a test 2 (2)cat -s file(删除额外空白 ...

  4. 玩转spring boot——结合阿里云持续交付

    前言 在互联网项目中,项目测试.部署往往需要花费大量时间.传统方式是在本地打包.测试完毕程序,然后通过ftp上传至服务器,再把测试的配置文件修改为生产环境的配置文件,最后重新运行服务.这一过程如果交给 ...

  5. [Linux] PHP程序员玩转Linux系列-腾讯云硬盘扩容挂载

    1.PHP程序员玩转Linux系列-怎么安装使用CentOS 2.PHP程序员玩转Linux系列-lnmp环境的搭建 3.PHP程序员玩转Linux系列-搭建FTP代码开发环境 4.PHP程序员玩转L ...

  6. kubernetes之coredns玩法

    一.概述 新版本的kubernetes默认使用了coredns,这里就不赘述了.直达车:https://coredns.io/.https://kubernetes.io/docs/tasks/adm ...

  7. 玩转Linux

    玩转Linux操作系统 说明:本文中对Linux命令的讲解都是基于名为CentOS的Linux发行版本,我自己使用的是阿里云服务器,系统版本为CentOS Linux release 7.6.1810 ...

  8. 使用grep命令,玩转代码审计寻找Sink

    好久没分享东西了,今天分享个实用代码审计技巧 使用grep,玩转代码审计,适用于linux/mac,windows需要另行安装grep: 使用场景如下:快速寻找项目中所有的Sink,快速寻找符合适配条 ...

  9. 玩转spring boot——快速开始

    开发环境: IED环境:Eclipse JDK版本:1.8 maven版本:3.3.9 一.创建一个spring boot的mcv web应用程序 打开Eclipse,新建Maven项目 选择quic ...

随机推荐

  1. 【BZOJ4241】历史研究 分块

    [BZOJ4241]历史研究 Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开 ...

  2. redis自启动

    $ vi /etc/init.d/redis # chkconfig: 2345 90 10 # description: Redis is a persistent key-value databa ...

  3. JavaScript原理学习

    悟透JavaScript(理解JS面向对象的好文章) http://www.cnblogs.com/leadzen/archive/2008/02/25/1073404.html Javascript ...

  4. 如何查看apache配置文件路径

    我是用https://lamp.sh/安装的,apache配置文件位置在:/usr/local/apache/conf/httpd.conf如果是直接安装的apache,配置文件应该在:/etc/ht ...

  5. 使用Spring AOP实现MySQL数据库读写分离案例分析

    一.前言 分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,更是最大限度了提高了应用中读取 (Read)数据的速度和并发量. 在进行数据库读写分离的时候,我们首先要进行数据库 ...

  6. jzyz集训 0612

    今天闵神找的题,题目质量还算不错,就是有些偏套路了. 第一题:定义一个排列是合法当且仅当这个排列中不存在大于2的循环节,询问有多少长度为n的排列是合法的且B排列是该排列的子序列. 恩...这题目其实不 ...

  7. .NET ViewState对于画面的速度影响

    最近开发一个.NET网站,发现有一个画面的交互特别缓慢,查了很多原因都没查到 最后终于知道,是因为画面的ViewState用的过多,其中有一个ViewState保存的数据相对而言比较大,导致了画面的运 ...

  8. 一篇文章了解相见恨晚的 Android Binder 进程间通讯机制【转】

    本文转载自:https://blog.csdn.net/freekiteyu/article/details/70082302 Android-Binder进程间通讯机制 概述 最近在学习Binder ...

  9. 使用.net实现ZooKeeper客户端

    最近在项目中用到ZooKeeper, 通过Java连接比较容易,.net项目就没那么容易,尤其对于不熟悉Linux的开发人员,这里写点搭建ZooKeeper测试环境的经验,供参考. 背景知识: Zoo ...

  10. iOS审核策略重磅更新:Guideline 2.1批量拒审

    自从进入了2018年,大量应用在AppStore提交审核后,都直接给大家回复了个新春大礼包 Guideline 2.1 - Information Needed. 而大部分的应用,特别是金融类相关AP ...