Bash脚本15分钟进阶教程

这里的技术技巧最初是来自谷歌的“Testing on the Toilet” (TOTT)。这里是一个修订和扩增版本。

Bash脚本15分钟进阶教程

脚本安全

我的所有bash脚本都以下面几句为开场白:

  1. #!/bin/bash
  2. set-o nounset
  3. set-o errexit

这样做会避免两种常见的问题:

  1. 引用未定义的变量(缺省值为“”)
  2. 执行失败的命令被忽略

需要注意的是,有些Linux命令的某些参数可以强制忽略发生的错误,例如“mkdir -p” 和 “rm -f”。

还要注意的是,在“errexit”模式下,虽然能有效的捕捉错误,但并不能捕捉全部失败的命令,在某些情况下,一些失败的命令是无法检测到的。(更多细节请参考这个帖子。)

脚本函数

在bash里你可以定义函数,它们就跟其它命令一样,可以随意的使用;它们能让你的脚本更具可读性:

  1. ExtractBashComments(){
  2. egrep "^#"
  3. }
  4. cat myscript.sh |ExtractBashComments| wc
  5. comments=$(ExtractBashComments< myscript.sh)

还有一些例子:

  1. SumLines(){# iterating over stdin - similar to awk
  2. local sum=0
  3. local line=””
  4. while read line ;do
  5. sum=$((${sum}+ ${line}))
  6. done
  7. echo ${sum}
  8. }
  9. SumLines< data_one_number_per_line.txt
  10. log(){# classic logger
  11. local prefix="[$(date +%Y/%m/%d\ %H:%M:%S)]: "
  12. echo "${prefix} $@">&2
  13. }
  14. log "INFO""a message"

尽可能的把你的bash代码移入到函数里,仅把全局变量、常量和对“main”调用的语句放在最外层。

变量注解

Bash里可以对变量进行有限的注解。最重要的两个注解是:

  1. local(函数内部变量)
  2. readonly(只读变量)
  1. # a useful idiom: DEFAULT_VAL can be overwritten
  2. # with an environment variable of the same name
  3. readonly DEFAULT_VAL=${DEFAULT_VAL:-7}
  4. myfunc(){
  5. # initialize a local variable with the global default
  6. local some_var=${DEFAULT_VAL}
  7. ...
  8. }

这样,你可以将一个以前不是只读变量的变量声明成只读变量:

  1. x=5
  2. x=6
  3. readonly x
  4. x=7# failure

尽量对你bash脚本里的所有变量使用local或readonly进行注解。

用$()代替反单引号(`)

反单引号很难看,在有些字体里跟正单引号很相似。$()能够内嵌使用,而且避免了转义符的麻烦。

  1. # both commands below print out: A-B-C-D
  2. echo "A-`echo B-\`echo C-\\\`echo D\\\`\``"
  3. echo "A-$(echo B-$(echo C-$(echo D)))"

用[[]](双层中括号)替代[]

使用[[]]能避免像异常的文件扩展名之类的问题,而且能带来很多语法上的改进,而且还增加了很多新功能:

操作符功能说明
||逻辑or(仅双中括号里使用)
&&逻辑and(仅双中括号里使用)
<字符串比较(双中括号里不需要转移)
-lt数字比较
=字符串相等
==以Globbing方式进行字符串比较(仅双中括号里使用,参考下文)
=~用正则表达式进行字符串比较(仅双中括号里使用,参考下文)
-n非空字符串
-z空字符串
-eq数字相等
-ne数字不等

单中括号:

  1. ["${name}" \> "a"-o ${name} \< "m"]

双中括号

  1. [["${name}">"a"&&"${name}"<"m"]]

相关推荐