位置: 编程技术 - 正文

关于Shell脚本效率优化的一些个人想法(shell脚本用法)

编辑:rootadmin
一、先说一下Shell脚本语言自身的局限性 作为解释型的脚本语言,天生就有效率上边的缺陷。尽管它调用的其他命令可能效率上是不错的。 Shell脚本程序的执行是顺序执行,而非并行执行的。这很大程度上浪费了可能能利用上的系统资源。 Shell每执行一个命令就创建一个新的进程,如果脚本编写者没有这方面意识,编写脚本不当的话,是非常浪费系统资源的。 二、我们在Shell脚本语言的局限性上尽可能的通过我们有经验的编码来提高脚本的效率。 1、比如我想做一个循环处理数据,可能是简单的处理一下数据,这样会让人比较容易就想到Shell里的循环类似这样: 我们可以使用time这个脚本来测试一下十万次循环的三次执行耗时: real 0m2.s user 0m1.s sys 0m0.s real 0m2.s user 0m2.s sys 0m0.s real 0m2.s user 0m1.s sys 0m0.s 平均耗时2.2s,如果你知道awk命令里的循环的话,那更好了,我们来测试一下同数据规模的循环三次执行耗时: real 0m0.s user 0m0.s sys 0m0.s real 0m0.s user 0m0.s sys 0m0.s real 0m0.s user 0m0.s sys 0m0.s 你都不敢想象平均时间仅0.s,基本上纯循环的效率已经比Shell高出两位数量级了。事实上你再跑百万次的循环你会发现Shell已经比较吃力了,千万级的更是艰难。所以你应该注意你的程序尽量使用awk来做循环操作。 2、关于正则,经常写Shell的同学都明白它的重要性,但是你真的能高效使用它吗? 下边举个例子:现在我有一个行的日志文件 action.log,它的内容类似: __ :: ... login old /***/port/***.php?… 我现在想获取//之间的port的字符串,我可以这样: awk -F'/' ‘{print $3}' < 7action.log > /dev/null 但是你不会想知道它的效率: real 0m.s user 0m.s sys 0m0.s 相信我,我不会再想看着光标闪秒的。但是如果这样执行: awk ‘{print $9}' < 7action.log | awk -F'/' '{print $3}' > /dev/null 这句的效率三次分别是: real 0m3.s user 0m5.s sys 0m0.s real 0m3.s user 0m5.s sys 0m0.s real 0m3.s user 0m5.s sys 0m0.s 平均时间大概3.6秒,这前后效率大概有4倍的差距,虽然不像上一个有百倍的差距,但是也足够让4小时变成1小时了。我想你懂这个差距的。 其实这个正则实例你可以尝试推测其他的情况,因为正则每次运行都是需要启动字符串匹配的,而且默认的分隔符会较快的按字段区分出。所以我们在知道一些数据规律之后可以尝试大幅度的缩短我们将要进行复杂正则匹配的字符串,这样会根据你缩减数据规模有一个非常明显的效率提升,上边还是验证的比较简单的正则匹配情况,只有一个单字符“”,你可以试想如果正则表达式是这样: $7!~/.jpg$/&&$7~/.[s]?html|.php|.xml|/$/&&($9==||$9==)&&$1!~/^.|^.|^.0|^..5/ 我想你可以想象的出一个目标匹配字符串从个字符缩减到个字符的时候的巨大意义! ps:另外详细的正则优化请看这个日期之后发的一篇博文。 3、再说一下shell的重定向和管道。这个条目我不会再举例子,只是说一下我个人的理解。 周所周知,很多程序或者语言都有一个比较突出的效率瓶颈就是IO,Shell也不例外(个人这么考虑)。所以建议尽可能的少用重定向来进行输入输出这样的操作或者创建临时文件来供后续使用,当然,如果必须这么干的时候那就这么干吧,我只是讲一个尽量的过程。 我们可以用Shell提供的管道来实现命令间数据的传递。如果进行连续的对数据进行过滤性命令的时候,尽量把一次性过滤较多的命令放在前边,这个原因都懂吧?减少数据传递规模。 最后我想说的连管道也尽量的少用的,虽然管道比正常的同定向IO快几个数量级的样子,但是那也是需要消耗额外的资源的,好好设计你的代码来减少这个开销吧。比如sort | uniq 命令,完全可以使用 sort -u 来实现。 4、再说一下Shell脚本程序的顺序执行。这块的优化取决于你的系统负载是否达到了极限,如果你的系统连命令的顺序执行负载都到了一个较高的线的话,你就没有必要进行Shell脚本程序的并行改造了。下边给出一个例子,如果你要模仿这个优化,请保证你的系统还能有负载空间。比如现在有这样一个程序: supportdatacommand1 supportdatacommand2 supportdatacommand3 supportdatacommand4 supportdatacommand5 supportdatacommand6 needdatacommand needdatacommand needdatacommand 大意就是有6个提供数据的命令在前边,后面有3个需要数据的命令,第一个需要数据的命令需要数据,第二个需要,第三个需要。但是正常情况下Shell会顺序的执行这些命令,从supportdatacommand1,一条一条执行到needdatacommand。这样的过程你看着是不是也很蛋疼?明明可以更好的做这一块的,蛋疼的程序可以这样改造: 可以类似上边的改造。这样改造之后蛋疼之感就纾解的多了。但还是感觉不是很畅快,那好吧,我们可以再畅快一点(我是指程序。。。),可以类似这样: 这样类似这样的改造,让有前后关系的命令放在一个for循环里让他们一起执行去,这样三个for循环其实是并行执行了。然后for循环内部的命令你还可以类似改造1的那种方式改造或者内嵌改造2这个的并行for循环,都是可以的,关键看你想象力了。恩?哦,不对,关键是看这些个命令之间是一种什么样的基友关系了。有关联的放一个屋里就行了,剩下的你就不用操心了。嘿嘿~~ 其实这个优化真的需要看系统负载。 5、关于对shell命令的理解。这个条目就靠经验了,因为貌似没有相关的书籍可看,如果谁知道有,请推荐给我,我会灰常感谢的啊。 比如:sed -n ',p' 和 sed -n 'q;,p' ,前者也是读取到行,后者也是,但是后者到行就执行了退出sed命令,避免了后续的操作读取。如果这个目标文件的规模巨大的话,剩下的你懂的。 还有类似sed ‘s/foo/bar/g' 和sed ‘/foo/ s/foo/bar/g' sed支持采用正则进行匹配和替换,考虑字符串替换的需求中,不防加上地址以提高速度。实例中通过增加一个判断逻辑,采用“事先匹配”代替“直接替换”,由于sed会保留前一次的正则匹配环境,不会产生冗余的正则匹配,因此后者具有更高的效率。关于sed命令的这两点优化,我也在sed命令详解里有提到。 还有类似sort 如果数字尽量用 -n选项;还有统计文件行数,如果每行的数据在占用字节数一样的情况时就可以ls查文件大小然后除以每行的数据大小的出行数,而避免直接使用wc -l这样的命令;还有find出来的数据,别直接就-exec选项了,如果数据规模小很好,但是如果你find出来上千条数据或更多,你会疯掉的,不,系统会疯掉的,因为每行数据都会产生新的进程,你可以这样find …. | xargs ….;还有…(如果你也知道类似的提效率情况请你告诉我共同进步!) 三、关于优化更好的一些选择 一个比较好的提升Shell脚本的效率方法就是…… 就是…… 就是…… 好吧,就是尽量少用Shell(别打我啊!!!)下边给出一些debian官方统计的一些在linux系统上边的各个语言的效率图,咱都以C++为比较基准(系统规格:x Ubuntu&#; Intel® Q® quad-core): 这些图的查看方法,比如第一个图java和c++的程序效率比较图,总共分三个部分,分别是time、memory、code的比较,如果是c++/java ,就是说 c++做比较的分子,java做比较的分母,如果图上的长条在哪边,说明所在的那边的程序使用的时间或者内存或者代码较多,具体多多少就看长条长了多少。每一部分有多个长条图形,每个长条图案表示针对程序处理不同方面的任务时进行的测试。比如第一幅,c++和java在该环境下大部分情况下time上是差不多的,甚至java-server还有稍微的优势,内存方面c++就有很大优势,能够使用比java少的多的内容做相同的事情,但是编码量c++就稍微多一点点。以下的图类似。

通过上边的图我看可以知道C++在时间和空间上对Python、Perl、PHP有着绝对压倒性的优势,但是相对的编码量较高。同java比只有内存使用上的优势。但是我们这篇主要是针对Shell的,但是,又是但是,debian官网没有把shell脚本纳入效率比较的统计范围啊!!!还是但是,我们知道Python、Perl、PHP都是号称对Shell在效率方面有着明显的优势,所以你如果不满意你通过以上提供的种种优化途径后的Shell脚本程序的话,那你就可以尝试换一种语言了。

但是我们往往不那么容易舍弃这么好用方便而且简单的处理数据方式,也可以有个折中的方法,你先用time测试各个Shell脚本命令的耗时,针对特别耗时,特别让人不能忍受的命令的效率使用C++程序处理,让你的Shell脚本来调用这个针对局部数据处理的C++程序,这样折中貌似还是能让人接受吧?

四、最后说一下这篇是不敢称为全面或者详解的文章,是我对这一段Shell学习和实践的一些心得,希望能有高手指点。也希望能帮到新踏入这一领域的新同学。以后有新的心得再添加吧。

感谢这篇文章的作者的博文指点。

-- ps:循环检测后台命令是否结束的判断修改: 解决方法暂时有两个(具体没有解释,不太清楚原因): 1、 2、 检查剩余个数的语句改成 jobs -l |grep -v “Done”|wc -l 第一个方案的解决是多执行一次jobs,可以解释成为了消除最后的Done结果,但是这种解释也是行不通的,因为循环是一直执行的,在echo里已经执行很多次jobs了,何止一次。 第二个方案是过滤掉jobs最后的输出结果Done这条语句。算是绕过问题得到了期待的结果。 个人感觉bash解释器优化掉了没有后台命令执行的jobs查询命令,如果是优化掉了那也应该有个空的返回,wc依然可以得到0的结果啊。所以这个问题找不到具体原因,如果你知道请告诉我,非常感谢。。。 这里先感谢just do shell群里的Eric 沉默的土匪 GS 三人,非常感谢你们的帮助。 这里两个方法不算好方法,只是奇怪这样为什么不行,行的又该如何解释。后来知道用wait命令就全解决了,耽误那么多时间还是用的不明智的方法。 转载请注明:三江小渡厚道喔!

推荐整理分享关于Shell脚本效率优化的一些个人想法(shell脚本用法),希望有所帮助,仅作参考,欢迎阅读内容。

关于Shell脚本效率优化的一些个人想法(shell脚本用法)

文章相关热门搜索词:shell脚本总结,shell脚本实例精讲,shell脚本应用实战,shell脚本常用命令及操作,shell脚本实例精讲,shell脚本应用实战,shell脚本应用实战,shell脚本作用,内容如对您有帮助,希望把文章链接给更多的朋友!

shell 基本计算、逻辑运算、位运算详解 以下面的格式提供运算表达式:$((expression))$echo$((5*(3+3)))$result=$(($myvar-))shell提供方便的数之间的进制转换:$echo$(())#八进制$echo$((0xA4))#十六进制还

hbase shell基础和常用命令详解 HBase是GoogleBigtable的开源实现,它利用HadoopHDFS作为其文件存储系统,利用HadoopMapReduce来处理HBase中的海量数据,利用Zookeeper作为协同服务。1.简介HBase是一

shell 中数学计算总结 1、错误方法举例a)var=1+1echo$var输出的结果是1+1,悲剧,呵呵b)var=1var=$var+1echo$var输出结果是1+1,依然悲剧,呵呵2、正确方法1)使用letvar=1let"var+=1"echo$var输

标签: shell脚本用法

本文链接地址:https://www.jiuchutong.com/biancheng/378330.html 转载请保留说明!

上一篇:BASH 学习笔记小结(bash 入门)

下一篇:shell 基本计算、逻辑运算、位运算详解(shell 计算表达式)

  • 一般纳税人税率有几种
  • 增值税发票认证在哪里
  • 小规模纳税人工程款税率是多少
  • 解除劳动合同支付违约金合法吗
  • 增值税专用发票使用规定 最新
  • 可供出售金融资产包括哪些内容
  • 先到发票后到商品怎么入账
  • 库存商品发出汇总表
  • 房地产企业汇算清缴
  • 收到公司退货会计分录
  • 医院收到卫生局补助会计分录怎么写
  • 外贸企业出口退税出口明细申报表
  • 房屋征收服务中心是干什么的
  • 加工属于什么税收分类
  • 认可的发票验证怎么弄
  • 小微企业劳务费税率
  • 旧房转让如何缴纳土地增值税
  • 回单是会计还是出纳职责
  • 收到税局代增值税专用发票已作废的退款怎么做账
  • 筹建期可以有收入吗
  • 广告费超标今年怎么处理
  • 怎么处理有问题的货物
  • 企业合并怎么处理
  • mac怎么连接校园网网线
  • win10怎么建立多个用户
  • 鸿蒙系统怎么自动填充密码
  • 英雄联盟怎么改左键移动
  • 成本加成法的缺点
  • 生产性生物资产包括哪些
  • 如何获取文件夹下所有文件
  • mac auto tune
  • Windows 11 Build 22000.176 (KB5006050) 更新推送(附更新内容+安装)
  • 异地工程预缴增值税怎么计算
  • 建筑工程简易计税可以抵扣吗
  • 公司买的手机怎么入账科目
  • 未开票的销售收入分录
  • 限额领料单一般一式几联
  • 企业转让要收多少费用
  • 电脑上fci是什么文件
  • 划转国有划拨土地流程
  • js获取网页链接
  • php 模拟post
  • 语言翻译算法
  • 增值税进项税额计算公式
  • 凭证摘要写错了已经结账
  • java hash()
  • 个税系统经营所得人员怎样添加
  • 加计扣除的增值税怎么做账
  • 销售应税服务或劳务的纳税义务发生时间的一般规定
  • 以前年度损益调整结转到本年利润吗
  • 劳务派遣和劳务承揽的区别
  • 刚成立公司没有发生业务,如何申报企业所得税
  • 什么情况下需要异地预缴增值税
  • 主营业务收入借方什么意思
  • 机动车转让后未过户原车主要承担赔偿责任
  • 劳务派遣差额扣除项目包含个人缴纳的社保费吗
  • 临时设施摊销属于什么资产
  • 自产自销免税发票可以抵税吗
  • 怎样充高速路etc现金
  • 为什么一般纳税人可以选择简易计税
  • win7跟xp怎样连接局域网
  • 连接远程mq
  • smsss.exe - smsss是什么进程
  • win8怎么一开机就进入桌面
  • windows关机电源不断电
  • linux查看所有硬件信息命令
  • windows7basic怎么改
  • windows8用的人少
  • Linux系统中下载文件的wget命令操作实例
  • Debian如何安装网卡驱动
  • Cocos2dx CCSprite CCSpriteFrame CCTexture2D CCAnimation学习总结
  • 安卓手机好用的笔记类app
  • cmd attribute
  • vue.js 开发工具
  • python默认方法
  • 兖州宁德新能源官网首页
  • 怎么屏蔽微信群消息,但是不退出此群
  • 江苏省常州市金坛区茅山风景区
  • 青椒课堂怎么激活登录
  • 机动驳船是什么
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设