前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux 命令:每日一学,参数传递之xargs命令实践

Linux 命令:每日一学,参数传递之xargs命令实践

作者头像
全栈工程师修炼指南
发布于 2024-10-11 10:45:42
发布于 2024-10-11 10:45:42
91803
代码可运行
举报
运行总次数:3
代码可运行

[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路 ]

0x01 前言简述

描述:上一章,我们学习了Linux中查找搜寻文件或目录的相关命令,此章我们学习常常与find命令联合使用,以及在Shell脚本中常用的参数替换 xargs 命令进行实践学习,从而实现更加强大的参数传递和多进程并行执行Linux命令或脚本等


0x02 参数替换

xargs 命令 - 将标准输入中的数据转换为命令行参数

描述:xargs(eXtended ARGuments)工具是给命令传递参数的一个过滤器,也是组合多个命令的一个工具。

由于很多命令不支持|管道来传递参数,此时就需要 xargs 命令的帮助,它可以读入stdin 的数据,并将格式化(空格符、回车符进行分隔)后的数据作为命令的参数,还可以将单行或多行文本输入转换为其他格式,例如,多行变单行以及单行变多行,后续实践我们会介绍到。

另外,许多命令不能接受过多的参数而导致命令执行失败,此时可以使用xargs 命令解决该问题。例如,使用 rm 命令删除百万级文件时会提示参数过多,这时可使用 find 命令 或 ls 命令 与 xargs 命令联用进行删除。。

工具功能:

将管道或标准输入(stdin)数据转换成命令行参数,也能够从文件的输出中读取数据。

将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。

默认命令是echo 意味着通过管道传递给 xargs 的输入将会包含换行和空白,不过通过 xargs 的处理,换行和空白将被空格取代。

它能够捕获一个命令的输出,然后传递给另外一个命令,

语法参数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 用法
command | xargs [OPTION]... COMMAND [INITIAL-ARGS]..

# 常用参数
-0        # 将NULL作为定界符。
-t        # 表示先打印命令,然后再执行。
-a FILE   # 指定一个参数文件,而不是从标准输入中读取。
-n NUM    # 指定每行显示多少NUM;
-L num    # 从标准输入一次读取 num 行送给 command 命令。 
-l        # 类似于-L,但如果未指定MAX-LINES,则默认为最多一个非空白输入行
-d '定界字符':    # 指定一个定界符注意必须是单字符;
-x, --exit        # 如果超过大小(参见-s),则退出。
-r no-run-if-empty # 当xargs的输入为空的时候则停止xargs,不用再去执行了。
-I R # 指定一个替换字符串{},这个字符串再xargs扩展时会被替换掉,-I与xargx联合使用的时候每一个参数命令都会被执行一次,类似于find的-ok/-exec选项
-i, --replace[=R] # 看linux支持了,将xargs的每项名称,一般是一行一行赋值给 {},可以用 {} 代替。
-n, --max-args=MAX-ARGS      # 每个命令最多使用MAX-ARGS参数行
-P, --max-procs=MAX-PROCS    # 一次运行最多的max-procs进程
-p, --interactive            # 批量运行命令前交互式提示
-s, --max-chars=MAX-CHARS    # 最多将命令限制为MAX-CHARS
-o, --open-tty # 在执行命令之前,在子进程中将stdin重新打开为/dev/tty;有助于运行

使用示例:

首先,定义一个测试用例文件,内有多行文本数据:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ cat test.txt
a b c d e f 
g h i j k l 
m n o p q r 
s t u v w x y z
  • 1.多行输入单行输出和指定行输出
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 示例1.默认情况下的多行变单行处理
cat test.txt | xargs  
  # a b c d e f g h i j k l m n o p q r s t u v w x y z

# 示例2.指定每行显示3个参数
cat test.txt | xargs -n3  
  # a b c 
  # d e f
  # g h i 

# 示例3.指定每行显示46个参数
cat test.txt | xargs -n4
cat test.txt | xargs -n6

# 示例4.每次处理 5 个文件,到/backup 目录下
find . -name "*.jpg" | xargs -n 5 cp -t /backup/
ls /backup/
  # 10.jpg  1.jpg  2.jpg  3.jpg  4.jpg  5.jpg  6.jpg  7.jpg  8.jpg  9.jpg

# 示例5.每次处理 10 个文件,移动到/destination 目录下
find /path/to/dir -name "*.jpg" | xargs -n 10 mv -t /destination/示例6.批量添加多个用户到linux中
echo user{1..10} | xargs -n1 useradd

weiyigeek.top-指定xargs处理参数后显示的列数

  • 2.指定一个定界符进行分割传递过来的参数字符串
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 默认情况下,xargs 是以换行符,或空格作为分隔符
echo -e "dir1\ndir2\ndir3" | xargs
  # dir1 dir2 dir3

echo "nameXWeiyiGeekXnameX全栈工程师修炼指南" | xargs -dX 
  # name WeiyiGeek name 全栈工程师修炼指南

# 显示成为两列,这是我们需要的格式
echo "nameXWeiyiGeekXnameX全栈工程师修炼指南" |  xargs -dX -n2  
  # name WeiyiGeek
  # name 全栈工程师修炼指南
  • 3.在执行命令之前进行确认,增加安全性:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
echo "file1.txt file2.txt file3.txt" | xargs -p rm
  # rm file1.txt file2.txt file3.txt ?...y
  • 4.自定义定义一个占位符,以便在 xargs 中替换特定字符串。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
echo "file1 file2 file3" | xargs -I {} mv {} {}.bak

# 示例1.复制所有图片文件到 /data/images/ 目录下,注意反斜杠
mkdir -vp /data/images/
ls *.png *.jpg *.gif | xargs -n1 -I {} cp {} /data/images/

# 示例2.查找当前目录下所有不可修改的文件 (对于入侵监测的时候可使用)
find . | xargs -I {} lsattr -a {} 2>/dev/null | grep '^----i'
  • 5.并行执行命令,提高效率。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 例1,同时压缩多个文件:
find . -name "*.log" | xargs -P 4 gzip

# 例2, 指定并行进程数为256,批量执行文件上传操作
thread_num=256
ls | xargs -n 1 -I {} -P ${thread_num} sh -c "/usr/binfs_upload_file /etcfs/client.conf {}"
ls -I '*.yml' | xargs -I {} rm -rf {}

# 例3.批量并行执行test.txt文件中,复制文件到到指定目录
cat test.txt <<'EOF'
cp ./0101/123456789.JPG  ../2023/0101/123456789.jpg
cp ./0102/123456789.JPG  ../2023/0102/123456789.jpg
cp ./0103/123456789.JPG  ../2023/0103/123456789.jpg
EOF
cat test.txt | xargs -n 1 -I {} -P 256 sh -c "{}" 

# 例4.并发执行多个进程进行文件下载
seq 100 | xargs -i -P10 wget -P /data http://share.weiyigeek.top/{}.zip

# 例5.并行下载B站视频
yum install python3-pip -y
pip3 install you-getseq 1 100 | xargs -i -P3 you-get https://www.bilibili.com/video/BV19D4y1D7UX?p={} 
  • 6.自定义处理空格和特殊字符
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 如果文件名中包含空格或特殊字符,可以使用 -print0 和 -0 选项,让参数以NULL分隔
find . -name "*.log" -print0 | xargs -0
  # ./audit/audit.log ./sssd/sssd_implicit_files.log ./sssd/sssd_nss.log 

# 或者使用 --null 选项,将换行符或空格作为文件名分隔符
find . -type f -name "*.log" -print0 | xargs -n1 --null 
  # ./audit/audit.log ./sssd/sssd_implicit_files.log ./sssd/sssd_nss.log 
  • 7.结合 find 命令使用的常规示例。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 例1.删除某个目录下的所有 .tmp 文件
# 使用用 rm 删除太多的文件时候,可能得到一个错误信息:/bin/rm Argument list too long. 用xargs解决此问题。
find /dir -name "*.tmp" | xargs rm -f

# 例2.查找当前目录下所有 .txt 文件并统计它们的行数:
find . -name "*.txt" | xargs wc -l

# 例3.NULL 字符作为换行符,并以三列显示
find . -type f -name "*.log" -print0 | xargs -0 -n3
# ./tuned/tuned.log ./audit/audit.log ./anaconda/anaconda.log
# ./anaconda/X.log ./anaconda/program.log ./anaconda/packaging.log
# ./anaconda/storage.log ./anaconda/ifcfg.log ./anaconda/ks-script-ECgRju.log

# 例4.统计文件信息,统计一个源代码目录中所有php文件的行数
find . -type f -name "*.php" -print0 | xargs -0 wc -l

# 例5,查找当前目录下所有的jpg 文件,并且压缩它们
find . -type f -name "*.jpg" -print | xargs tar -czvf images.tar.gz

# 例6. 查询带有 SUID SHID SBIT 等权限的文件
find /bin -perm -7000 | xargs ls -Sl
  • 8.读取stdin将格式化后的参数传递给命令
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 假设一个命令为 weiyigeek.sh 和一个保存参数的文件arg.txt:
# weiyigeek.sh 脚本命令内容,打印出所有参数
tee weiyigeek.sh <<'EOF'
#!/bin/bash 
echo $*  
EOF

# arg.txt 文件内容:
aaa
bbb
ccc

# 可以利用这个来更改ip文本以及脚本参数的传入
cat arg.txt | xargs -I {} ./weiyigeek.sh -p {} -l 
cat arg.txt | xargs -I {} echo $* "-p123" {}"- l123"
-p aaa -l 
-p bbb -l 
-p ccc -l
  • 9.在xargs中,可以使用 $* 获取所有参数, 以此来进行格式化拼接输出。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 方式1.使用xargs格式化之后输出
cat url.txt | xargs -I {} echo $* "Url:"{}"/admin/web.jsp"

# 也可以使用awk一步搞定,后续我们也要介绍文件处理三剑客之一的命令
awk '{print "Url:"$1"/admin/web.jsp"}' url.txt
# Url:http://demo1.weiyigeek.top/admin/web.jsp
# Url:http://demo2.weiyigeek.top/admin/web.jsp
# Url:http://demo3.weiyigeek.top/admin/web.jsp

weiyigeek.top-使用xargs格式化之后输出

  • 10.将 xargs 与其他命令结合使用,进行更复杂的操作:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 例1.查找所有 .log 文件中包含 "Error" 的行,并对结果进行排序和去重,最后统计每个唯一行的出现次数
find /path/to/dir -name "*.log" | xargs grep "Error" | sort | uniq -c

# 假2,有一个文件包含了很多你希望下载的URL,你能够使用xargs下载所有链接
cat url-list.txt | xargs -P10 wget -c 
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-10-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈工程师修炼指南 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
解Bug之路-记一次调用外网服务概率性失败问题的排查
和外部联调一直是令人困扰的问题,尤其是一些基础环境配置导致的问题。笔者在一次偶然情况下解决了一个调用外网服务概率性失败的问题。在此将排查过程发出来,希望读者遇到此问题的时候,能够知道如何入手。
无毁的湖光-Al
2019/10/22
1.9K2
解Bug之路-记一次调用外网服务概率性失败问题的排查
从Linux源码看TIME_WAIT状态的持续时间
笔者一直以为在Linux下TIME_WAIT状态的Socket持续状态是60s左右。线上实际却存在TIME_WAIT超过100s的Socket。由于这牵涉到最近出现的一个复杂Bug的分析。所以,笔者就去Linux源码里面,一探究竟。
呆呆
2021/05/23
1.7K0
解Bug之路-Nginx 502 Bad Gateway
事实证明,读过Linux内核源码确实有很大的好处,尤其在处理问题的时刻。当你看到报错的那一瞬间,就能把现象/原因/以及解决方案一股脑的在脑中闪现。甚至一些边边角角的现象都能很快的反应过来是为何。笔者读过一些Linux TCP协议栈的源码,就在解决下面这个问题的时候有一种非常流畅的感觉。
无毁的湖光-Al
2020/07/27
1.9K0
解Bug之路-Nginx 502 Bad Gateway
从Linux源码看Socket(TCP)Client端的Connect
笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情。 今天笔者就来从Linux源码的角度看下Client端的Socket在进行Connect的时候到底做了哪些事情。
无毁的湖光-Al
2020/06/30
1.6K0
从Linux源码看Socket(TCP)Client端的Connect
被微信面麻了,问的太细节了。。。
上周有个读者在面试微信的时候,被问到既然打开 net.ipv4.tcp_tw_reuse 参数可以快速复用处于 TIME_WAIT 状态的 TCP 连接,那为什么 Linux 默认是关闭状态呢?
小林coding
2021/12/27
8200
被微信面麻了,问的太细节了。。。
从linux源码看socket的close
笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情。上篇博客讲了socket的阻塞和非阻塞,这篇就开始谈一谈socket的close(以tcp为例且基于linux-2.6.24内核版本)
无毁的湖光-Al
2018/08/14
5.7K0
从linux源码看socket的close
重传问题四阶段优化分享
使用wrk模拟http压力打nginx时,发现压测过程中持续出现重传现象,而且在高压下和低压下都会出现不同程度的重传。
mingjie
2022/05/12
1.1K0
重传问题四阶段优化分享
深入分析网络编程中踩过的坑
网络编程中经常会遇到一些异常的情况,定位问题需要了解协议栈的实现,以下是工作中遇到的一些常见问题的深入分析和解决思路。 问题1:server端业务进程响应心跳超时被监控进程kill,导致数据或者逻辑异常 我们的后台框架采用的是proxy,worker模型,proxy处理连接和会话,worker处理业务,proxy和worker之间通过共享内存队列进行通信,并有监控进程扫描proxy和worker的运行情况。管理进程会定时向worker发起心跳查询,防止业务进程挂起。业务worker的心跳默认是60s,如
QQ音乐技术团队
2018/01/30
2.4K0
深入分析网络编程中踩过的坑
Linux系统研究 - 操作系统是如何管理tcp连接的 (2)
接上一篇文章 Linux系统研究 - 操作系统是如何管理tcp连接的 (1),我们再来继续讲。
KINGYT
2019/11/07
3.3K1
记一次Redis连接池问题引发的RST
如图所示,服务器发送了大量的 reset,在我 watch 的时候还在发,多半有问题。
LA0WAN9
2021/12/14
1.2K0
记一次Redis连接池问题引发的RST
tcp rst报文_TCP报文格式
对于TCP客户端,在发送完SYN报文之后,如果接收到的回复报文同时设置了ACK和RST标志,在检查完ACK的合法性之后,处理RST标志,关闭套接口。对于ACK确认序号,其应当大于第一个未确认序号(snd_una),并且,确认序号不应大于未发送数据的序号(snd_nxt)。
全栈程序员站长
2022/11/10
1.7K0
TIME_WAIT过多的解决办法
执行主动关闭的那端经历了这个状态,并停留MSL(最长分节生命期)的2倍,即2MSL。
全栈程序员站长
2022/06/27
1.2K0
tcp_tw_recycle和tcp_timestamps导致connect失败问题
转载自: http://blog.sina.com.cn/s/blog_781b0c850100znjd.html
shirishiyue
2021/08/08
1.8K0
linux tcp的timewait如何解决
timewait在tcp结束后主动关闭一方的等待时候的行为。图片中的服务和客户端描述不是非常准确,这里客户端是主动关闭一方。(在web服务器模型下,web服务器也可主动关闭客户端,这个时候web服务器就变成了四次握手的客户端)。
全栈程序员站长
2022/06/28
2.1K0
linux tcp的timewait如何解决
麻了,被字节问懵逼了!
之前有个读者在秋招面试的时候,被问了这么一个问题:SYN 报文什么时候情况下会被丢弃?
小林coding
2021/12/27
6320
麻了,被字节问懵逼了!
一分钟告诉面试官TIME_WAIT
[FIN_WAIT1] :FIN_WAIT1和FIN_WAIT2均为等待对方的FIN报文。两者区别为,当SOCKET在ESTABLISHED状态时,想主动关闭连接从而想对方发送FIN报文,此时进入FIN_WAIT1状态。当收到ACK报文进入FIN_WAIT2状态。
我是程序员小贱
2020/06/29
1.5K0
不要启用 net.ipv4.tcp_tw_recycle
本文为翻译英文BLOG《Coping with the TCP TIME-WAIT state on busy Linux servers》,但并非完整的翻译,译者CFC4N对原文理解后,进行了调整,增加了相关论点论据,跟原文稍有不同。翻译的目的,是为了加深自己知识点的记忆,以及分享给其他朋友,或许对他们也有帮助。文章比较长,没耐心请点关闭。
sunsky
2020/08/20
7.7K0
不要启用 net.ipv4.tcp_tw_recycle
可恶,又被小林装到了!
他抓到一个抓包图,客户端和服务端四次挥手后,客户端在 17 秒内又复用了与上一次连接相同的端口,向服务端发起了 SYN 报文, 并成功建立了连接。
小林coding
2022/05/21
3010
可恶,又被小林装到了!
解Bug之路-dubbo流量上线时的非平滑问题
笔者最近解决了一个困扰了业务系统很久的问题。这个问题只在发布时出现,每次只影响一两次调用,相较于其它的问题来说,这个问题有点不够受重视。由于种种原因,使得这个问题到了业务必须解决的程度,于是就到了笔者的手上。
呆呆
2021/05/21
5830
TCP TIME_WAIT解决办法
** 若TIME_WAIT事件设置过短, 会导致错误后果 TIME_WAIT结束过早, 导致之前迷失的第三次握手突然到达, 新连接突然成功
平凡的学生族
2019/12/24
2.4K0
TCP TIME_WAIT解决办法
相关推荐
解Bug之路-记一次调用外网服务概率性失败问题的排查
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档