编写高效的bash脚本
来源:互联网 发布:软件测试培训中心 编辑:程序博客网 时间:2024/05/19 22:03
1. 尽量将awk脚本写在bash脚本中,而不是放在单独的文件中。
在使用awk时,如果要有对较复杂的对文本的处理,我们习惯将其写在一个单独的文件中,使用时,如:
echo "${params}"|awk -f conf/generate_sum.awk
但是这样会带来一定的性能的损耗。
推荐将awk脚本写在bash中,如,上面的例子可以写为:
echo "${params}"|awk ' BEGIN{
FS项目="&"
i=0
}
{
for(i=1;i<=NF;i++){
l=index($i,"=");
str=str substr($i,0,l);
}
}
END{
print str
}'
试验:
采用上面的awk来分析一个75k的网页文件,循环100次。
采用第一种写法平均用时:43s
采用第二种写法平均用时:40s
在本次试验中,采用第二种写法能提高效率6.9%
对于sed脚本,同样有以上的建议。
2. 能用管道连接起来的一系列操作不要分开写。
管道帮助我们将一个程序的输出导入到另一个程序的输入。在处理数据时,很多时候需要一系列的处理。如果可以使用一系列的管道将处理连接起来,就尽量不要将每个处理分开来做。
例如:
我们用下列操作来得到数据link:
link=$(echo "${params}"|awk -f conf/generate_sum.awk)
link=$(echo "$link"|sum -s)
link=$(echo "$link"|awk -F" " '{print $1}')
也可以采用如下的方法:
link=$(echo "${params}"|awk -f conf/generate_sum.awk|sum -s|awk -F" " '{print $1}')
实践表明采用方式二的效率会好些。
试验:
采用上面的脚本来处理一个75k的网页,循环100次。
采用第一种写法平均用时:73s
采用第二种写法平均用时:45s
在本次试验中,采用第二种写法能提高效率38.4%
3. 可以不使用管道时,减少管道的使用。
一个简单的例子是在文件的字符匹配时,我们可以使用
cat someweb|grep “href”
也可以使用
grep “href” someweb
推荐使用第二种方式。
试验:
采用上面的脚本循环10000次,得到的数据是:
采用第一种写法平均用时:13s
采用第二种写法平均用时:7s
第二种写法能提高效率46%
4. 尽可能的减少IO操作。
这点毋庸置疑。但是还是有些其他要说的。
在脚本运行中,许多中间变量的保存可以使用文件,尤其是父shell进程和子shell进程交互时,使用文件是比较方便的。其实,也有许多其他的方法。
这里要说一下父shell进程和子shell进程数据的共享。
一个问题是,子shell进程的环境变量,父shell进程是取不到的。如:
cat file|while read x
do
((line++))
done
printf “there are %d lines” $line
这时就打印不到行数。
解决的方法有:
使用文件保存line值,这里不推荐。
使用全局变量。
使用重定向。
这里推荐使用重定向。原因见下一条。
5. 尽量使用重定向,不用cat
如果对所有的脚本进行一下统计,那么使用的最多的几个命令当中,肯定有cat。
如果你关心脚本的效率,那就尽早放弃cat。(下面的数据可能会更有说服力)
而实际上,cat能完成的功能,基本都可以用重定向来完成。
对于条目4的例子:
cat file|while read x
do
((line++))
done
推荐采用重定向完成:
(这同时也解决了父shell进程和子shell进程数据共享的问题)
while read x
do
((line++))
done < file
试验:
采用上面的脚本循环100次,文件为75k网页文件,得到的数据是:
采用第一种写法平均用时:11s
采用第二种写法平均用时:1s
第二种写法能提高效率91%
6. 不要使用递归
确实,bash也可以使用递归。
如果你才知道,那就当不知道吧。因此bash递归的效率非常的低。
7. 尽量使用内置命令,而不用同样功能的系统命令
对于内置命令,(可以通过man builtin查看),在执行的时候是不会产生子shell进程的。因此其执行速度会远远的高于系统命令。
例如:echo是一个bash内置的命令。当然,也存在和其功能相同的一个系统命令,名字也叫echo,在/bin/echo。这两个的性能差距是很大的。
我们可以比较下面两个简单的脚本:
/bin/echo "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" >/dev/null
和
echo "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" >/dev/null
试验:
采用上面的脚本循环20000次,得到的数据是:
采用第一种写法平均用时:13s
采用第二种写法平均用时:<1s
第二种写法能提高效率92%以上。
因此,在遇到一个功能的需求时,优先使用内置命令或其组合来完成,而不用系统或自己提供的命令和程序。
8. 其他
在你优化你的C代码的时候,很多程序设计的思想也是可以用到bash脚本设计中的。比如循环的优化,代码的模块化,结构化等。
实际上,对于一个脚本的优化,我们总是先找到其瓶颈在什么地方,然后考虑采用什么方法来进行。如果用尽所有方法也无法提高这块脚本的效率时,可以考虑将这块功能用C来实现。如果同时还考虑开发效率,那么可以考虑使用其他的脚本语言:perl,python等。
- 编写高效的bash脚本
- Linux 中高效编写 Bash 脚本的 10 个技巧
- Linux高效编写Bash脚本的10个技巧
- Linux 中高效编写 Bash 脚本的 10 个技巧
- Linux中高效编写Bash脚本的10个技巧
- 简单bash脚本的编写
- 非常好的BASH脚本编写教程
- 非常好的BASH脚本编写教程
- 非常好的BASH脚本编写教程(转)
- 非常好的BASH脚本编写教程
- 非常好的BASH脚本编写教程
- 非常好的BASH脚本编写教程
- 编写健壮的Bash shell脚本
- 非常好的BASH脚本编写教程(转)
- 非常好的BASH脚本编写教程
- 非常好的BASH脚本编写教程
- 编写健壮的Bash shell脚本
- 编写健壮的Bash shell脚本
- Javascript中的利用原形链和对象冒充创建类
- 32bit和64bit的区别
- 腾讯笔试题1
- J2ME游戏开发实例讲解(1)
- 樱花飘雪
- 编写高效的bash脚本
- 在Resize事件强制刷新控件的大小
- SQL2005安装问题 性能监视器计数器要求
- 程序员之窗
- 腾讯笔试2
- WEB监控体系之设备负载监控
- 基本数据结构的python实现---队列
- C# 学习笔记
- 开篇叙述