原文地址:https://www.lujun9972.win/blog/2020/04/01/既生xargs何生parallel/index.html

目录

  • xargs 不能很好的处理特殊字符(比如空格, \, ' 和 ")
  • xargs 没有参数直接按CPU Core数量来并法运行任务,而必须人工指定并法度
  • xargs 可能会导致输出串行
  • xargs 不支持保持多任务输出的顺序
  • xargs 不支持远程运行任务
  • xargs 不支持context替换
  • xargs使用 -I 选项时,只能替代一个参数.
  • 当命令中包含复合命令,管道或IO重定向时,xargs需要将之包装在 bash -c中

xargs和parallel都能并发运行多个命令,然而对这两个命令的区别一直不太清楚,直到看到了这篇文章:https://www.gnu.org/software/parallel/parallel_alternatives.html#DIFFERENCES-BETWEEN-xargs-AND-GNU-Parallel

简单的说,parallel就是增强版的xargs。

xargs 不能很好的处理特殊字符(比如空格, \, ' 和 ")

比如下面这个例子

touch important_file
touch 'not important_file'
ls not* | xargs rm

会删除 import_file,并提示 rm: 无法删除 'not': 没有那个文件或目录

mkdir -p "My brother's 12\" records"
ls | xargs rmdir

会提示 /usr/bin/xargs: 未匹配的 单 引用;默认情况下,引用是针对 xargs 的,除非您使用了 -0 选项rmdir: 删除 'My' 失败: 没有那个文件或目录

touch 'c:\windows\system32\clfs.sys'
echo 'c:\windows\system32\clfs.sys' | xargs ls -l

会提示: ls: 无法访问 'c:windowssystem32clfs.sys': 没有那个文件或目录

一般遇到这种情况你需要使用xargs的 -0 参数来指定使用 NUL 作为分隔符,然而这同时要求产生输入的命令的支持。

还有一种变通方案是使用 xargs 的 -d 选项指定使用换行符作为分隔符,比如:

touch 'c:\windows\system32\clfs.sys'
touch 'not important_file'
ls |xargs -d "\n" -n1 rm

xargs 没有参数直接按CPU Core数量来并法运行任务,而必须人工指定并法度

在parallel默认依据CPU Core数量来决定并发的任务数,而且除了能通过 -P N 直接设定并发度外,还能通过 -P +N, -P -N, -P N% 来在CPU Core的数量基准进行调整(减少N个,增加N个,乘于N%)

而xargs只能通过 -P N 来手工设定并法度, 不过这也不是什么太大的问题,我们可以通过 grep processor /proc/cpuinfo |wc -l 来统计CPU的Core数量

xargs 可能会导致输出串行

也就是可能一行输出的前半部分是一个进程的输出,而后半部分是另一个进程的输出。例如:

slow_seq() {echo Count to "$@"seq "$@" |perl -ne '$|=1; for(split//){ print; select($a,$a,$a,0.100);}'
}
export -f slow_seq
echo "这是期望值"
seq 8 | xargs -n1 -P1 -I {} bash -c 'slow_seq {}'
echo "使用parallel进行并发"
seq 8 | parallel -P8 slow_seq {}
echo "使用xargs进行并发"
seq 8 | xargs -n1 -P8 -I {} bash -c 'slow_seq {}'

这是期望值
Count to 1
1
Count to 2
1
2
Count to 3
1
2
3
Count to 4
1
2
3
4
Count to 5
1
2
3
4
5
Count to 6
1
2
3
4
5
6
Count to 7
1
2
3
4
5
6
7
Count to 8
1
2
3
4
5
6
7
8
使用parallel进行并发
Count to 1
1
Count to 2
1
2
Count to 3
1
2
3
Count to 4
1
2
3
4
Count to 5
1
2
3
4
5
Count to 6
1
2
3
4
5
6
Count to 7
1
2
3
4
5
6
7
Count to 8
1
2
3
4
5
6
7
8
使用xargs进行并发
Count to 1
Count to 2
Count to 3
Count to 4
11Count to 5
11Count to 6
Count to 7
1Count to 8
1112222222333333444445555666778

xargs 不支持保持多任务输出的顺序

parallel 可以通过 -k--keep-order 选项来保证多任务的输出顺序与顺序执行时的顺序一直。

而xargs无此功能,也就是说任务有多行输出的话,可能导致多个任务的输出混杂在一起.

xargs 不支持远程运行任务

parallel可以通过 --sshlogin 来将任务发送到远程主机上并发运行.

其他与远程运行的命令包括 --ssh, --return, --transfer, --transferfile, --tf, --cleanup, --env

这个能力极其恐怖,下面是摘自 man parallel 中的一个远程执行任务的例子:

EXAMPLE: Using remote computersTo run commands on a remote computer SSH needs to be setup and you must be able to login without entering apassword (The commands ssh-copy-id, ssh-agent, andsshpass may help you do that).If you need to login to a whole cluster, you typically donot want to accept the host key for every host. You wantto accept them the first time and be warned if they areever changed. To do that:# Add the servers to the sshloginfile(echo servera; echo serverb) > .parallel/my_cluster# Make sure .ssh/config existtouch .ssh/configcp .ssh/config .ssh/config.backup# Disable StrictHostKeyChecking temporarily(echo 'Host *'; echo StrictHostKeyChecking no) >> .ssh/configparallel --slf my_cluster --nonall true# Remove the disabling of StrictHostKeyCheckingmv .ssh/config.backup .ssh/configThe servers in .parallel/my_cluster are now added in.ssh/known_hosts.To run echo on server.example.com:seq 10 | parallel --sshlogin server.example.com echoTo run commands on more than one remote computer run:seq 10 | parallel --sshlogin s1.example.com,s2.example.net echoOr:seq 10 | parallel --sshlogin server.example.com \--sshlogin server2.example.net echoIf the login username is foo on server2.example.net use:seq 10 | parallel --sshlogin server.example.com \--sshlogin foo@server2.example.net echoIf your list of hosts is server1-88.example.net withlogin foo:seq 10 | parallel -Sfoo@server{1..88}.example.net echoTo distribute the commands to a list of computers, make afile mycomputers with all the computers:server.example.comfoo@server2.example.comserver3.example.comThen run:seq 10 | parallel --sshloginfile mycomputers echoTo include the local computer add the special sshlogin':' to the list:server.example.comfoo@server2.example.comserver3.example.com:GNU parallel will try to determine the number of CPUs oneach of the remote computers, and run one job per CPU -even if the remote computers do not have the same numberof CPUs.If the number of CPUs on the remote computers is notidentified correctly the number of CPUs can be added infront. Here the computer has 8 CPUs.seq 10 | parallel --sshlogin 8/server.example.com echo

xargs 不支持context替换

parallel 的 -X 选项可以让 {} 替换成命令行参数允许的最多参数值,若并发运行多个任务,则这些参数会被平均地分给每个任务,这种多参数的替换被称为context替换。例如

seq 1 123|parallel -X -I{} echo {}

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 27 28 29 30 31
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123

xargs使用 -I 选项时,只能替代一个参数.

xargs的 -I 选项默认了 -L 1,也就是说每个命令行只能使用最多一行输入作为参数。

而parallel中没有这个限制

seq 1 11 |parallel -I{} -l 2 echo

1 2
3 4
5 6
7 8
9 10
11

当命令中包含复合命令,管道或IO重定向时,xargs需要将之包装在 bash -c中

在xargs中,若将命令用括号引用起来,则xargs将整个括号的内容当成是一个命令名,也就是类似于parallel中的 -q 选项:

所以当你执行

ls | xargs -d "\n"  -I {} "wc {} >{}.wc"

时,xargs会尝试查找一个叫做 wc XXX>XXX.wc 的命令,结果就是提示找不到该命令。

正确的做法是改成

ls | xargs -d "\n" -P8 -I {} bash -c "wc {} >{}.wc"

而使用parallel就没那么复杂了,直接用引号引起来就行了:

ls | parallel "wc {} >{}.wc"

既生xargs何生parallel相关推荐

  1. 小学生计算机舞蹈,最近“泼水成画”很火?舞蹈生VS体育生,看到计算机:你是来添乱的?...

    最近泼水拍照非常的流行,不知道大家在私底下有没有关注过这个视频,而且在这个视频中,这些花放在水里确实也特别的好看,接下来就一起来看一下,不同的学生拍出来的泼水照片都是什么样的. 首先大家看到的就是舞蹈 ...

  2. 既生瑜何生亮 access_token VS refresh_token

    中国有句老话, 既生瑜何生亮, 既然有我周瑜在世, 为什么老天还要一个诸葛亮啊? 同样的, 众所周知, 在 OAuth 2.0 授权协议中, 也有两个令牌 token , 分别是 access_tok ...

  3. excel如何找到高频词_拟录取后:应届生和往届生档案哪里找;重灾院校区;高频词背诵表...

    今日消息1.应届生和往届生档案哪里找?2.重灾院校区3.考研云督学班高频词背诵表汇总1.应届生和往届生档案哪里找? 往年这个时候论文答辩.复试已经结束,已经进入毕业季!现在你们毕业答辩结束了吗?你们都 ...

  4. python 数学基础_Python3数学基础 - 随笔分类 - 既生喻何生亮 - 博客园

    本系列主要集中于数学知识点,利用python编程描述以往学过的数学知识. 摘要:Kronecker delta 克罗内克函数 Wiki "维基百科" Kronecker delta ...

  5. 转贴:既生瑜何生亮:FreeBSD与Linux再比较

    原贴:http://www.phpchina.com/8051/viewspace_8240.html 传说中FreeBSD比linux稳定,大型网站几乎都建立在FreeBSD系统上,我一直疑惑难道l ...

  6. 计算机系男生生的都是女儿吗,IT男只能生女孩,生男孩几率很小吗?

    "IT男"即指男性网络编辑员.计算机维修工.数据库系统管理员.游戏程序开发师等,"IT"系信息技术.互联网技术.信息论等的缩写.据业内人士传辐射会降低精子活力, ...

  7. 应届生和往届生,报名条件区别汇总!

    即将预报名,今天给大家整理了一下应届生和往届生报名需要注意的点.填写信息和报名需要的材料,大家一定要认真对待. 1 关于应届生和往届生身份确认 应届生是指2022年的毕业生,含普通高校.成人高校.普通 ...

  8. 应届生和往届生,谁更容易考研成功?

    据教育部统计,2017年共201万人报考,其中,应届考生113万人,往届考生88万人:2018年共238万人报考,其中,应届考生131万人,往届考生107万人.从数据可知,2017年,往届生考研人数占 ...

  9. 计算机往届生考研失败找工作,终于发现应届生和往届生考研复试会被歧视吗-考研复习...

    对于20考研的学生来说,或许这一段时间比较的焦虑,一方面是初试成绩公布在即,另一方面,复试准备还在摸索中,有很多问题困扰着我们的考研大学生.而在诸多的复试问题中,其中关于应届生和往届生二者之间,是否会 ...

最新文章

  1. IDEA 出现 updating indices 卡进度条问题的解决方案并加快索引速度
  2. SPOJ MYQ10 (数位DP)
  3. PS教程第十五课:图层是最基本的要求
  4. PL\SQL结构控制、异常
  5. python列表删除多个相同元素_Python遍历列表删除多个元素或者重复元素
  6. 在centos7中安装flutter,执行flutter --version时显示flutter的版本为v0.0.0 unknown
  7. 深信服桌面云盒子需要服务器吗,为何众多客户选择深信服桌面云?主要看实力...
  8. 人工智能--符号计算--笔记
  9. 康佳android 9tv,汇总:康佳电视机型与软件对应关系速查表 附电视升级方法
  10. 自然语言处理入门 第一章 新手上路
  11. DLang 编译实验
  12. 谁来PK“百度局域网”
  13. 搜索功能(二)-搜索页面——搜索栏基本布局
  14. 魔兽世界70人最多服务器,数据告诉你,《魔兽世界》TBC怀旧服有多受欢迎
  15. “区块链+农业”助力乡村振兴
  16. html5的交互式微课,交互式微课这样制作更轻松
  17. 华为国际快递被转运至美国 联邦快递致歉:误送
  18. 辞退既然不给离职在证明的易迅天空公司
  19. HttpClient-v4.5官方文档翻译
  20. CMake基础教程(19)find_library查找库路径

热门文章

  1. 遥感影像云检测-传统方法-:Haze Optimized Transformation(HOT)方法
  2. workflow 的审批流程的业务实现一
  3. 进行域名解析时,递归和迭代查询方式是什么意思?
  4. 区块链-链上云计算应用技术沙龙
  5. 软件测试--两个星期的工作经历
  6. windows cmd cd进入目录无效
  7. [从头读历史] 第255节 孔子和他的《春秋》 [BC657至BC598]
  8. 114 Three.js实现深度遮挡的下雨特效
  9. qt 判断文件是否存在
  10. 股票代码是什么意思?