xargs命令详解,xargs与管道的区别

在工作中经常会接触到xargs命令,特别是在别人写的脚本里面也经常会遇到,但是却很容易与管道搞混淆,本篇会详细讲解到底什么是xargs命令,为什么要用xargs命令以及与管道的区别。为什么要用xargs呢,我们知道,linux命令可以从两个地方读取要处理的内容,一个是通过命令行参数,一个是标准输入。例如cat、grep就是这样的命令,举个例子:

1
echo 'main' | cat test.cpp

这种情况下cat会输出test.cpp的内容,而不是'main'字符串,如果test.cpp不存在则cat命令报告该文件不存在,并不会尝试从标准输入中读取。echo 'main' | 会通过管道将 echo 的标准输出(也就是字符串'main')导入到 cat 的标准输入,也就是说此时cat的标准输入中是有内容的,其内容就是字符串'main'但是上面的内容中cat不会从它的标准输入中读入要处理的内容。(注:标准输入是有一个缓冲区的,就像我们在程序中使用scanf函数从标准输入中读取一样,实际上是从标准输入的缓冲区中读取的)。其实基本上linux的命令中很多的命令的设计是先从命令行参数中获取参数,然后从标准输入中读取,反映在程序上,命令行参数是通过main函数 int main(int argc,char*argv[]) 的函数参数获得的,而标准输入则是通过标准输入函数例如C语言中的scanf读取到的。他们获取的地方是不一样的。例如:

1
echo 'main' | cat

这条命令中cat会从其标准输入中读取内容并处理,也就是会输出 'main' 字符串。echo命令将其标准输出的内容 'main' 通过管道定向到 cat 的标准输入中。

1
cat

如果仅仅输入cat并回车,则该程序会等待输入,我们需要从键盘输入要处理的内容给cat,此时cat也是从标准输入中得到要处理的内容的,因为我们的cat命令行中也没有指定要处理的文件名。大多数命令有一个参数  -  如果直接在命令的最后指定 -  则表示从标准输入中读取,例如:

1
echo 'main' | cat -

这样也是可行的,会显示 'main' 字符串,同样输入 cat - 直接回车与输入 cat 直接回车的效果也一样,但是如果这样呢:

1
echo 'main' | cat test.cpp -

同时指定test.cpp 和 - 参数,此时cat程序还是会显示test.cpp的内容。但是有一个程序的策略则不同,它是grep,例如:

1
echo 'main' | grep 'main' test.cpp -

该命令的输出结果是:
test.cpp:int main()
(standard input):main

此时grep会同时处理标准输入和文件test.cpp中的内容,也就是说会在标准输入中搜索 'main' 也会在文件 test.cpp (该文件名从grep命令行参数中获得)中搜索 'main'。也就是说当命令行中 test.cpp 和 - 两个参数同时存在的时候,不同的程序处理不同。我们看到了cat与grep处理就不同。但是有一点是一样的,首先在命令行中查找要处理的内容的来源(是从文件还是从标准输入,还是都有),如果在命令行中找不到与要处理的内容的来源相关的参数则默认从标准输入中读取要处理的内容了。

另外很多程序是不处理标准输入的,例如 kill , rm 这些程序如果命令行参数中没有指定要处理的内容则不会默认从标准输入中读取。所以:

1
echo '516' | kill

这种命里是不能执行的。

1
echo 'test' | rm -f

这种也是没有效果的。

这两个命令只接受命令行参数中指定的处理内容,不从标准输入中获取处理内容。想想也很正常,kill 是结束进程,rm是删除文件,如果要结束的进程pid和要删除的文件名需要从标准输入中读取,这个也很怪异吧。 但是像 cat与grep这些文字处理工具从标准输入中读取待处理的内容则很自然。

但是有时候我们的脚本却需要 echo '516' | kill 这样的效果,例如 ps -ef | grep 'ddd' | kill 这样的效果,筛选出符合某条件的进程pid然后结束。这种需求对于我们来说是理所当然而且是很常见的,那么应该怎样达到这样的效果呢。有几个解决办法:

1. 通过 kill `ps -ef | grep 'ddd'`    
#这种形式,这个时候实际上等同于拼接字符串得到的命令,其效果类似于  kill $pid

2. for procid in $(ps -aux | grep "some search" | awk '{print $2}'); do kill -9 $procid; done   
#其实与第一种原理一样,只不过需要多次kill的时候是循环处理的,每次处理一个

3. ps -ef | grep 'ddd' | xargs kill  
#OK,使用了xargs命令,铺垫了这么久终于铺到了主题上。xargs命令可以通过管道接受字符串,并将接收到的字符串通过空格分割成许多参数(默认情况下是通过空格分割) 然后将参数传递给其后面的命令,作为后面命令的命令行参数

回到顶部

xargs是什么,与管道有什么不同

xargs与管道有什么不同呢,这是两个很容易混淆的东西,看了上面的xargs的例子还是有点云里雾里的话,我们来看下面的例子弄清楚为什么需要xargs:

echo '--help' | cat
输出:
--help

echo '--help' | xargs cat
输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Usage: cat [OPTION]... [FILE]...
Concatenate FILE(s), or standard input, to standard output.
  -A, --show-all           equivalent to -vET
  -b, --number-nonblank    number nonempty output lines
  -e                       equivalent to -vE
  -E, --show-ends          display $ at end of each line
  -n, --number             number all output lines
  -s, --squeeze-blank      suppress repeated empty output lines
  -t                       equivalent to -vT
  -T, --show-tabs          display TAB characters as ^I
  -u                       (ignored)
  -v, --show-nonprinting   use ^ and M- notation, except for LFD and TAB
      --help     display this help and exit
      --version  output version information and exit
With no FILE, or when FILE is -, read standard input.
Examples:
  cat f - g  Output f's contents, then standard input, then g's contents.
  cat        Copy standard input to standard output.
Report cat bugs to bug-coreutils@gnu.org
GNU coreutils home page: <http://www.gnu.org/software/coreutils/>
General help using GNU software: <http://www.gnu.org/gethelp/>
For complete documentation, run: info coreutils 'cat invocation'

可以看到 echo '--help' | cat   该命令输出的是echo的内容,也就是说将echo的内容当作cat处理的文件内容了,实际上就是echo命令的输出通过管道定向到cat的输入了。然后cat从其标准输入中读取待处理的文本内容。这等价于在test.txt文件中有一行字符 '--help' 然后运行  cat test.txt 的效果。

而 echo '--help' | xargs cat 等价于 cat --help 什么意思呢,就是xargs将其接受的字符串 --help 做成cat的一个命令参数来运行cat命令,同样  echo 'test.c test.cpp' | xargs cat 等价于 cat test.c test.cpp 此时会将test.c和test.cpp的内容都显示出来。

回到顶部

xargs的一些有用的选项

信到这里应该都知道xargs的作用了,那么我们看看xargs还有一些有用的选项:

1. -d 选项
默认情况下xargs将其标准输入中的内容以空白(包括空格、Tab、回车换行等)分割成多个之后当作命令行参数传递给其后面的命令,并运行之,我们可以使用 -d 命令指定分隔符,例如:
echo '11@22@33' | xargs echo
输出:
11@22@33
默认情况下以空白分割,那么11@22@33这个字符串中没有空白,所以实际上等价于 echo 11@22@33 其中字符串 '11@22@33' 被当作echo命令的一个命令行参数

echo '11@22@33' | xargs -d '@' echo
输出:
11 22 33
指定以@符号分割参数,所以等价于 echo 11 22 33 相当于给echo传递了3个参数,分别是11、22、33

2. -p 选项
使用该选项之后xargs并不会马上执行其后面的命令,而是输出即将要执行的完整的命令(包括命令以及传递给命令的命令行参数),询问是否执行,输入 y 才继续执行,否则不执行。这种方式可以清楚的看到执行的命令是什么样子,也就是xargs传递给命令的参数是什么,例如:
echo '11@22@33' | xargs -p -d '@'  echo
输出:
echo 11 22 33
 ?...y      ==>这里询问是否执行命令 echo 11 22 33 输入y并回车,则显示执行结果,否则不执行
 11 22 33   ==>执行结果

3. -n 选项
该选项表示将xargs生成的命令行参数,每次传递几个参数给其后面的命令执行,例如如果xargs从标准输入中读入内容,然后以分隔符分割之后生成的命令行参数有10个,使用 -n 3 之后表示一次传递给xargs后面的命令是3个参数,因为一共有10个参数,所以要执行4次,才能将参数用完。例如:

echo '11@22@33@44@55@66@77@88@99@00' | xargs -d '@' -n 3 echo
输出结果:
11 22 33
44 55 66
77 88 99
00
等价于:
echo 11 22 33
echo 44 55 66
echo 77 88 99
echo 00
实际上运行了4次,每次传递3个参数,最后还剩一个,就直接传递一个参数。

4. -E 选项,有的系统的xargs版本可能是-e  eof-str
该选项指定一个字符串,当xargs解析出多个命令行参数的时候,如果搜索到-e指定的命令行参数,则只会将-e指定的命令行参数之前的参数(不包括-e指定的这个参数)传递给xargs后面的命令
echo '11 22 33' | xargs -E '33' echo
输出:
11 22

可以看到正常情况下有3个命令行参数 11、22、33 由于使用了-E '33' 表示在将命令行参数 33 之前的参数传递给执行的命令,33本身不传递。等价于 echo 11 22 这里-E实际上有搜索的作用,表示只取xargs读到的命令行参数前面的某些部分给命令执行。

注意:-E只有在xargs不指定-d的时候有效,如果指定了-d则不起作用,而不管-d指定的是什么字符,空格也不行。

echo '11 22 33' | xargs -d ' ' -E '33' echo  => 输出 11 22 33
echo '11@22@33@44@55@66@77@88@99@00 aa 33 bb' | xargs -E '33' -d '@' -p  echo  => 输出 11 22 33 44 55 66 77 88 99 00 aa 33 bb

## -0 选项表示以 '\0' 为分隔符,一般与find结合使用

find . -name "*.txt"
输出:
./2.txt
./3.txt
./1.txt     => 默认情况下find的输出结果是每条记录后面加上换行,也就是每条记录是一个新行

find . -name "*.txt" -print0
输出:
./2.txt./3.txt./1.txt     => 加上 -print0 参数表示find输出的每条结果后面加上 '\0' 而不是换行

find . -name "*.txt" -print0 | xargs -0 echo
输出:
./2.txt ./3.txt ./1.txt

find . -name "*.txt" -print0 | xargs -d '\0' echo
输出:
./2.txt ./3.txt ./1.txt

xargs的 -0 和 -d '\0' 表示其从标准输入中读取的内容使用 '\0' 来分割,由于 find 的结果是使用 '\0' 分隔的,所以xargs使用 '\0' 将 find的结果分隔之后得到3个参数: ./2.txt ./3.txt ./1.txt  注意中间是有空格的。上面的结果就等价于 echo ./2.txt ./3.txt ./1.txt

实际上使用xargs默认的空白分隔符也是可以的  find . -name "*.txt"  | xargs  echo   因为换行符也是xargs的默认空白符的一种。find命令如果不加-print0其搜索结果的每一条字符串后面实际上是加了换行

转载于:https://www.cnblogs.com/tunian/p/9924085.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/388045.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pytorch回归_PyTorch:用岭回归检查泰坦尼克号下沉

pytorch回归In this notebook, we shall use this dataset containing data about passengers from the Titanic. Based on this data, we will use a Ridge Regression model which just means a Logistic Regression model that uses L2 Regularization for predicting wheth…

Java后台与VUE跨域交接

后台代码&#xff1a;package com.cn.Mr.Zhong.filter;import org.springframework.stereotype.Component;import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;impor…

koa2 中使用 svg-captcha 生成验证码

1. 安装svg-captcha $ npm install --save svg-captcha 2. 使用方法 生成有4个字符的图片和字符串const svgCaptcha require(svg-captcha)const cap svgCaptcha.create({size: 4, // 验证码长度width:160,height:60,fontSize: 50,ignoreChars: 0oO1ilI, // 验证码字符中排除 …

Weblogic 节点启动

1.启动管理理节点export JAVA_OPTIONS"$JAVA_OPTIONS -Dcom.sun.xml.namespace.QName.useCompatibleSerialVersionUID1.0 -Djava.security.egdfile:/dev/./urandom"nohup ./startWebLogic.sh >admin.log &tail -f admin.log2.启动节点ssonohup ./startManaged…

[Swift]LeetCode74. 搜索二维矩阵 | Search a 2D Matrix

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号&#xff1a;山青咏芝&#xff08;shanqingyongzhi&#xff09;➤博客园地址&#xff1a;山青咏芝&#xff08;https://www.cnblogs.com/strengthen/&#xff09;➤GitHub地址&a…

iris数据集 测试集_IRIS数据集的探索性数据分析

iris数据集 测试集Let’s explore one of the simplest datasets, The IRIS Dataset which basically is a data about three species of a Flower type in form of its sepal length, sepal width, petal length, and petal width. The data set consists of 50 samples from …

Oracle 12c 安装 Linuxx86_64

1)下载Oracle Database 12cRelease 1安装介质 官方的下载地址&#xff1a; 1&#xff1a;http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html 2&#xff1a;https://edelivery.oracle.com/EPD/Download/get_form?egroup_aru_number16496…

Linux入门实验

学习Linux要先做实验来熟悉操作系统本次先写点入门的操作。 关于Linux入门实验的操作如下&#xff1a; 【例1】显示当前使用的shell [rootcentos7 ~]# echo ${SHELL} /bin/bash 【例2】显示当前系统使用的所有shell [rootcentos7 ~]#cat /etc/shells /bin/sh /bin/bash /usr/bi…

flink 检查点_Flink检查点和恢复

flink 检查点Apache Flink is a popular real-time data processing framework. It’s gaining more and more popularity thanks to its low-latency processing at extremely high throughput in a fault-tolerant manner.Apache Flink是一种流行的实时数据处理框架。 它以容…

917. 仅仅反转字母

给定一个字符串 S&#xff0c;返回 “反转后的” 字符串&#xff0c;其中不是字母的字符都保留在原地&#xff0c;而所有字母的位置发生反转。 示例 1&#xff1a; 输入&#xff1a;"ab-cd" 输出&#xff1a;"dc-ba"示例 2&#xff1a; 输入&#xff1a;&q…

C# socket nat 映射 网络 代理 转发

using System;using System.Collections.Generic;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;namespace portmap_net{/// <summary>/// 映射器实例状态/// </summary>sealed internal class state{#region Fields (5)pu…

python初学者_初学者使用Python的完整介绍

python初学者A magical art of teaching a computer to perform a task is called computer programming. Programming is one of the most valuable skills to have in this competitive world of computers. We, as modern humans, are living with lots of gadgets such as …

c# nat udp转发

UdpClient myClient;Thread recvThread;//打开udp端口开始接收private void startRecv(int port){myClient new UdpClient(port);recvThread new Thread(new ThreadStart(receive));recvThread.Start();}//停止接收private void stopRecv(){recvThread.Abort();}private void…

【Code-Snippet】TextView

1. TextView文字过长&#xff0c;显示省略号 【参考】 必须要同时设置XML和JAVA&#xff0c;而且&#xff0c;java中设置文字必须是在最后。 android:ellipsize"start|end|middle" //省略号的位置 android:singleLine"true" android:lines"2"…

Object 的静态方法之 defineProperties 以及数据劫持效果

再提一下什么是静态方法&#xff1a; 静态方法&#xff1a;在类身上的方法&#xff0c;  动态方法:在实例身上的方法 Object.defineProperties(obj, props)obj&#xff1a;被添加属性的对象props&#xff1a;添加或更新的属性对象给对象定义属性&#xff0c;如果存在该属性&a…

Spring实现AOP的4种方式

Spring实现AOP的4种方式 先了解AOP的相关术语: 1.通知(Advice): 通知定义了切面是什么以及何时使用。描述了切面要完成的工作和何时需要执行这个工作。 2.连接点(Joinpoint): 程序能够应用通知的一个“时机”&#xff0c;这些“时机”就是连接点&#xff0c;例如方法被调用时、…

如何使用Plotly在Python中为任何DataFrame绘制地图的卫星视图

Chart-Studio和Mapbox简介 (Introduction to Chart-Studio and Mapbox) Folium and Geemap are arguably the best GIS libraries/tools to plot satellite-view maps or any other kinds out there, but at times they require an additional authorization to use the Google…

Java入门系列-26-JDBC

认识 JDBC JDBC (Java DataBase Connectivity) 是 Java 数据库连接技术的简称&#xff0c;用于连接常用数据库。 Sun 公司提供了 JDBC API &#xff0c;供程序员调用接口和类&#xff0c;集成在 java.sql 和 javax.sql 包中。 Sun 公司还提供了 DriverManager 类用来管理各种不…

3.19PMP试题每日一题

在房屋建造过程中&#xff0c;应该先完成卫生管道工程&#xff0c;才能进行电气工程施工&#xff0c;这是一个&#xff1a;A、强制性依赖关系B、选择性依赖关系C、外部依赖关系D、内部依赖关系 作者&#xff1a;Tracy19890201&#xff08;同微信号&#xff09;转载于:https://…

Can't find temporary directory:internal error

今天我机子上的SVN突然没有办法进行代码提交了&#xff0c;出现的错误提示信息为&#xff1a; Error&#xff1a;Cant find temporary directory:internal error 然后试了下其他的SVN源&#xff0c;发现均无法提交&#xff0c;并且update时也出现上面的错误信息。对比项目文件…