See You Again

几个技巧让你的shell脚本脱颖而出

shell是*NIX系统下的脚本语言,凭借其简单、强大、灵活、实用等特性而深受广大程序员的喜爱。由于脚本语言的灵活性,很多新手写出来的脚本质量欠佳,甚至酿成了悲剧。

本篇介绍几个常用的shell语法技巧,让你的脚本脱颖而出。

定义变量

当同一个内容出现多次的时候就要考虑用变量去替换掉它,这几乎适用于所有的编程。在写脚本的时候要特别注意,因为很容易忽略这点。
shell里面建议用大写,以区分普通的变量:

  1. PACK_DIR=/home/user/pack_center

使用命令列表

shell里面的列表语法(&&、||)有点类似 if/else 结构,但是更简洁。多用这种语法不仅让你的脚本更易读,而且能提高脚本质量。

看一个极端的例子(不好风格):

  1. cd $PACK_DIR
  2. rm -rf *

可能作者的原意是先切换到 $PACK_DIR 目录,然后删除下面的所有文件,但是这里有一个隐患,如果目录不存在(cd执行出错)就会删掉非预期的文件,从而酿成悲剧。其实这里有一层隐含的意思,即首先上一个命令要执行成功,列表语法完美的解决了这个问题:

  1. cd $PACK_DIR && rm -rf *

稍微复杂点的应用:

  1. grep -iq application.mode $CONF && sed -i 's/application.mode/mode/g' $CONF || echo 'Not found application.mode in $CONF'

上面用列表的语法表达了它的意思:如果 $CONF 文件里有 application.mode 字符串,就全部替换为 mode,否则就打印一句日志。

更进一步,执行多条语句的情况:

  1. A && B && C && D && ...
  2. A || B || C || D || ...
  3. A && { B; C; D; } || { E; F; }

当然了,使用这种语法一定要控制住不要‘走火入魔’,如果太复杂就改为 if/else 结构。原则上一行代码表达一个意思,但不能为了追求一行而牺牲可读性。

利用shell的通配符扩展

shell提供了通配符扩展的功能,让你的脚本更加强大,常用的如 * {} ? [],注意这个跟正则表达式可不是一回事。

一些使用通配符的例子(通配扩展之后可操作多个对象):

  1. rm ./{package,dist,tmp}/*
  2. mkdir -p ./{dir1,dir2/sub21,dir3/{sub31,sub32}}
  3. ls 2015-1?-2[0123].log

变量修饰

建议对变量都加上必要的修饰(引号、大括号),防止意外产生,例如:

  1. ${BASH}_VERSION
  2. ${10}
  3. [ "$day" = yes ]

变量替换

shell是一种基于字符串的编程语言,它在变量里内置了多种操作语法以达到对字符串强大的控制能力:

  1. url='http://www_sina_com_cn/path/index.html'
  2. echo ${url//_/.}
  3. echo ${url#http://}
  4. echo ${url%%/*}
  5. echo ${name:=$USER}

使用函数

如果你的脚本有多次相同的调用,可以封装到函数里。
通常函数里的变量加上 local 声明为局部变量。

  1. killps (){
  2. ps ux |grep "$1" |grep -v 'grep' |awk '{print $2}' |while read id;do kill $id; done
  3. }

熟悉常用的命令行工具

例如 find grep awk sed,这些工具有很强大的参数或者语法,熟悉之后能让你更上一层楼。

几个看起来比较‘高深’的应用举例:

  1. find /home/user/log/ -type f ! \( -name "*.bz2" -o -name "*.gz" \) -mmin +120 -exec bzip2 {} \; >/dev/null 2>&1
  2. awk '!a[$0]++' in.txt
  3. grep keyword -r . --include \*.cpp --include \*.h

其他

基础语法、概念的了解和熟悉,比如管道,重定向,环境变量,参数变量,正则表达式等等,在此之上通过实践逐步提高自己的脚本技能。

更多参考

2015-11-03 喜欢

Copyright © 2015-2018 转载请注明出处

回到顶部 ↑