Shell脚本执行效率

一、引言
低效的shell脚本设计会进一步影响原本解释器模式下并不见长的程序运行效率,使其在面对大数据量文本分析时的资源与时间消耗变成难以接受的。本文分析了shell语言及其应用需求的特点,从分层设计的角度提出了“自底向上进行shell脚本编程”的理论,同时提出了从“外部系统环境”到“内部执行模式”全面的掌握工具软件的方法。实例充分证明,自底向上的shell脚本编程思想及方法能够有效提高脚本的执行效率。
作为解释型的脚本语言,天生就有效率上边的缺陷。尽管它调用的其他命令可能效率上是不错的。
Shell脚本程序的执行是顺序执行,而非并行执行的。这很大程度上浪费了可能能利用上的系统资源。
Shell每执行一个命令就创建一个新的进程,如果脚本编写者没有这方面意识,编写脚本不当的话,是非常浪费系统资源的。
hell脚本开发便是这样一个整体的编程过程:基于shell结构化程序设计语言,并通过调用上述工具软件,形成类似命令批处理程序的shell脚本。shell与工具软件的紧密联系使得shell脚本开发具有鲜明的“自底向上”编程风格。掌握shell脚本编程既要熟悉shell程序设计语言,同时也要熟练掌握find/sed/awk/grep等各种工具软件。

二、 shell脚本优化的意义
编写高效的shell脚本,这不仅是出于优秀程序员对精简高效程序的追求,更为了满足实际的应用需求。shell是一种解释型语言,尽管从执行方式方面考虑,解释型程序的效率上比不上C语言等编写的编译型程序,但脚本其所具有的简便快捷的特点使其能够有效实现对系统任务和重复性任务的自动化管理操作,普遍应用在日常的数据处理之中。

系统管理员在进行系统信息采集或网站日志处理中经常要面对从上百万或更大数据量的文件中提取、分析数据的需求,实际上优化shell脚本效率的效用直接体现在这种大数据量的文本处理上。低效的shell脚本设计会进一步影响原本解释型执行模式下并不见长的shell脚本运行效率,特别是在面对大数据量文本分析时的资源与时间消耗变成难以接受的。

此外,程序的优化需要有针对性,盲目的优化是费时费力的。“过早的优化,是万恶之源”。算法大师Donald E. Knuth曾分析到:程序员经常会由于预先的判断错误把97%的时间花费在优化非关键模块的效率之上,却只花了3%的时间在关键模块上,因此过早的优化是没必要的,只有确定了关键模块的真正所在,对其进行的优化才是有价值的。如何有针对性的去优化shell脚本,提高脚本执行效率?

三、 shell脚本优化的方法
从shell的编程模式来看,shell结构语言与各应用软件紧密结合的特色使shell编程具有鲜明的自底向上的编程风格。Shell和系统分别提供各种内置函数和工具软件,这些工具软件相当于程序设计中可重用的模块代码, 并且是采用C语言等语言开发的高效模块。这些工具软件的使用大大弥补了shell作为解释器在效率上的缺陷。同时尽管在应用需求上存在交叉,不同的工具具有不同的执行模式使其在解决同一个需求也存在效率上的差别,因此,采用何种工具直接影响着shell脚本的执行效率。

下边是一个工具软件应用效率的体现实例 :

需求:计算1到100000累加结果

方法1:采用bash shell的数值计算

# time for((i=0;i<=100000;i++)); do ((sum+=i)); done ; echo $sum

real 0m1.134s

user 0m1.080s

sys 0m0.048s

5000050000

方法2:采用awk的数值计算

# time awk ‘BEGIN{while(i++<100000)sum+=i; printf “%d”, sum;}’

5000050000

real 0m0.029s

user 0m0.020s

sys 0m0.000s

实例结果分析:同等的累加运算,采用shell的数值计算耗时1.134秒,采用awk工具只需要0.029秒。实验结果表明,适当的采用工具软件,能够明显提高shell脚本的执行效率。

“一个程序只做一件事,并做好。程序要能协作。程序要能处理文本流,因为这是最通用的接口”,shell脚本开发便是这样一种“自底向上”的编程过程,这种过程既充分体现了UNIX的编程哲学,也体现了模块化结构式程序的模块化思想及其封装性与紧凑性。这种紧凑性表现在shell编程中必备的各种工具内部功能的精简,高效和无冗余。shell充分利用了这些工具,提高了脚本的适用范围。

基于shell脚本的“自底向上”的编程风格,可以从工具软件的挑选和应用方向考虑优化程序效率。而工具软件的挑选与应用,离不开以下二点:

a:系统原理知识的了解及应用

b:工具软件的执行模式的了解及应用

系统是工具软件的外部条件和应用环境,执行模式是软件的内部环境,只有由里到外对工具软件进行全面的了解,才能够结合实际需求和设计,提高脚本执行效率。

计算shell脚本的执行时间

#!/bin/bash
start=`date +%s`
ls -al >/dev/null 2>&1

sleep 5s
end=`date +%s`
dif=$[ end - start ]
echo $dif

四、 系统原理及应用
1.文件系统
了解操作系统相关原理能够帮助更好的理解、掌握并应用工具软件。首先以文件系统为例,只有了解LINXU的根文件系统,才能更好的理解find命令查找文件时的深度优先查找方式。再比如:通常LINUX文件系统包括存放于文件索引列表的文件相关信息和存放于磁盘数据块中的实际数据。有部分命令是采用索引列表里的文件信息,有些命令则需要去遍历数据。根据需求采用适当的工具才能提高脚本执行效率。

实例 :文件系统应用

需求:计算定长大数据量文件的总记录数

方法1:采用wc命令,在文件遍历过程中累计文件记录数。

方法2:采用ls命令,读取索引中的文件大小信息,除以单条记录长度即可获得总记录数。

实例结果分析:方法2的效率在于充分利用了文件系统和需求,减少了文件I/O和遍历计算。在大文件处处理中的效率提高程序尤为明显。

2 管道
管道是UNIX及其兼容系统中最早也最通用的进程间通信(IPC)手段,shell采用管道线简便实现了管道应用,管道已经普通采用于各种shell脚本程序中。

只有了解文件系统,多进程编程等相关知识方能更好的掌握管道的应用。管道实质上是内核基于在内存中构造的管道文件系统(PIPEFS)实现的。父子进程一端采用只读方式打开文件,另一端采用只写的方式。命名管道则是进一步利用了文件系统使应用管道的进程脱离了父子关系的限制。另外,BASH中的每一条的管道都是在其子进程环境中运行的,基于进程间环境的独立性,管道内的变量操作并不会对父进程同名变量产生影响。

通过管道线将多个存在数据流依赖的命令进行重定向和连接,既实现了进程间通信,又避免了数据流落地产生了IO消耗和临时文件处理工作。

3 正则
shell中的正则是形式语言学中正则语言理论的实际应用。形式语言探究的是语言的内容和规则的严格论证。构成语言的基本要素是字符集和在其之上的语法定义。shell中存在的诸多正则标准或称流派便是根源于各标准支持的不同的元字符定义和对基本规则的扩展;此外正则表达式的应用过程分为分析,编译,执行三个过程。通常将正则在这过程中所采用的不同的数据结构与匹配算法归类为不同的正则引擎,主要包括DFA和NFA二种方式。DFA正则引擎采用确定型有限自动机模型,对每个输入字符都有确定的输入状态,对于字符串只需要一遍扫描即可完成算法。所以DFA引擎效率较高,但支持的功能较少;后者采用非定型有限自动机模型,增加了回溯机制,使得能够支持环视,非贪婪等功能,但也因为回溯影响了效率。

正是基于不同的正则标准使得正则表达式总是要在复杂性,效率,与准确性三点进行平衡。一般来说,对于相同目的的正则表达式复杂度会随着准确性提高并且影响效率。不同的工具软件支持的正则标准也存在差别。如何优化正则是一个较大的话题,可以参考《精通正则表达式》一书。

正则是文本匹配的利器,被广泛应用于字符串匹配之中,而字符串匹配往往是进行文本增加、删除、修改、查询等操作的基础前提。从效率上考虑,尽管正则使用起来十分方便,但出于效率考虑,正则却未必是最好的选择。实际的shell脚本开发中需要了解各种工具所支持的正则标准和正则匹配脚本运行中占用的时间比,在开发过程中结合实际需求,考虑是否需要采用正则,然后再考虑采用哪种工具哪种正则标准。

实例:正则效率。

需求:某文本以空格和/进行分隔,获取第五列的内容.

方法1:采用正则[ /]分别匹配二种分隔符,取得第五列

# time awk -F’[ /]’ ‘{print $5}’ a.txt >/dev/null

real 0m17.717s

user 0m14.749s

sys 0m2.844s

方法2:实际数据分析中发现,可以采用单字符解析的方式,首先根据“空格”分隔符取得第4列,再利用“/”分隔符取得第二列。

# time awk ‘{print $4}’ a.txt |awk -F/ ‘{print $2}’ >/dev/null

real 0m0.565s

user 0m0.224s

sys 0m0.688s

实例结果分析:awk采用-F指定分隔符,在多分隔符情况下,会启用正则去解析记录,增加了函数调用,和字符串匹配的消耗,效率上理所当然的比不上默认的空格或单字符分隔符采用的简单的字符比较方式,尽管如此,方法2依赖于对需求的进一步分析,适用的需求范围没有使用正则那么简便灵活。

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: shell脚本可以通过调用mysql命令来执行SQL语句。例如,可以使用以下命令执行SQL语句: mysql -h主机名 -u用户名 -p密码 数据库名 -e "SQL语句" 其中,主机名是数据库所在的主机名,用户名和密码是数据库的登录凭据,数据库名是要执行SQL语句的数据库名称,SQL语句是要执行的SQL语句。 例如,以下是一个简单的shell脚本,用于执行SQL语句并将结果输出到文件中: #!/bin/bash mysql -hlocalhost -uroot -p123456 testdb -e "SELECT * FROM users" > output.txt 该脚本将连接到名为testdb的数据库,并执行SELECT * FROM users语句,将结果输出到output.txt文件中。 ### 回答2: Shell脚本是一种用于Unix和Linux系统的脚本语言,可以用于管理文件系统、执行命令等。在Shell脚本中,我们可以使用各种命令和工具来完成一些常见的任务,其中SQL是一个常见的用途之一。 执行SQL语句需要一个数据库管理系统(DBMS),比如MySQL和Oracle等。一般来说,我们需要首先在Shell脚本中安装适合的DBMS并建立连接。连接数据库后,我们可以使用Shell脚本执行SQL语句并获取返回值。 我们可以使用以下命令在Shell脚本执行SQL: 1. mysql命令 这是一个常见的用于管理MySQL数据库的命令,可以直接在Shell执行SQL语句。我们可以使用以下命令来运行我们的SQL语句: mysql -u user -p password -h hostname -P port -D dbname -e "SQL statement" 其中,-u指定用户名,-p指定密码,-h指定主机名,-P指定端口号,-D指定数据库名,-e指定要执行的SQL语句。 2. psql命令 这是一个用于管理PostgreSQL数据库的命令,也可以在Shell执行SQL。类似于mysql命令,我们可以使用以下命令来运行我们的SQL语句: psql -h hostname -p port -U username -d dbname -c "SQL statement" 其中,-h指定主机名,-p指定端口号,-U指定用户名,-d指定数据库名,-c指定要执行的SQL语句。 有些时候,我们需要在Shell脚本执行多条SQL语句或者使用循环来动态执行SQL,这就需要对Shell脚本的编程能力有一定的要求了。但无论在哪种情况下,我们都需要了解DBMS和Shell脚本的基本语法才能编写出安全高效的代码。 ### 回答3: Shell脚本是一种在Unix或Linux操作系统中使用的编程语言,其脚本文件使用Shell解释器来执行执行SQL语句通常是在数据库中操作数据,与shell脚本紧密相关,尤其是在自动化任务方面。 在Shell脚本执行SQL语句的过程: 1. 指定数据库连接信息:需要在Shell脚本中指定数据库连接信息,包括数据库服务器IP地址、数据库端口、登录名和密码等。可以将这些信息定义为变量,然后在脚本中使用这些变量,方便修改和维护。 2. 编写SQL语句:在Shell脚本中编写需要在数据库中执行的SQL语句。这些SQL语句可以是查询、插入、更新或删除等操作。注意在写SQL语句时候要通过变量的方式传值,防止SQL注入。 3. 执行SQL语句:通过shell执行数据库客户端程序例如 mysql,postgresql,oracle等,同时传递执行的SQL语句。 4. 处理结果:执行SQL语句后,可以获取数据库执行结果,包括数据库操作受影响的行数、查询结果等。可以通过Shell脚本来处理这些结果,比如进行统计、分析、输出等操作。 在实际应用中,Shell脚本执行SQL通常被用于批量处理数据、自动化任务或数据备份等场景,如某个时期对数据进行统计,定时清洗过期数据或导出数据报表。通过Shell脚本执行SQL语句可以极大提高效率,降低手动操作过程中出错可能,保证数据一致性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值