用BASH编程已有些时间了,参与过大型项目的开发。当初的摸石子过河,项目越来越大了,代码开始腐朽了。
也许,从新开始是件好事,如同老板所说,背上太多的包袱,你如何前行!
下面,我从DRY(Dont’t Repeat Yourself)和KISS(Keep it Simple & Smart),这两条
最重要的编程原则来展示一下我在新项目中的实践。
1. assert
及时发现错误,C代码中assert就是这样一个用处,很多时间,我们的程序员并不对命
令的执行进行返回码检查,其主要原因是,怕麻烦,且使用大量的if判断增加了代码
的冗余,如下所示。
function fn_main() { cp <span class="katex math inline">src</span>dst if [ $? -ne 0 ]; then echo "cp fail" return 1 fi}我们可以构造一个BASH版的assert,称其为xt(assert的缩写)
PS8="eval echo /<span class="katex math inline">{BASH_SOURCE##*/}/|/$LINENO/|: "function xt() { [ "</span>{1}" -eq 0 ] && return <span class="katex math inline">{1} echo</span>{@:2} || return <span class="katex math inline">? return</span>{1}}
那么上面的代码改写如下:
function fn_main() { cp <span class="katex math inline">src</span>dst xt <span class="katex math inline">? `</span>PS8` "cp fail" || return <span class="katex math inline">?}
使用xt有两个明显的好处:
a. 大大减少检查代码的行数
b. 函数调用层次较多时,如果出错了,可以打印出调用栈
2. 关于日志
当前的代码现状:
a. 写代码时不写日志
b. 只有自己的提示信息,没有错误输出,往往命令的错误输出才是查错的关键
function fn_main() {
fn_cp</span>src1 <span class="katex math inline">dst1 # 没有日志
fn_cp</span>src2 <span class="katex math inline">dst2 || echo "cp fail" ></span>logfile # 不小心把日志清空了
fn_cp <span class="katex math inline">src3</span>dst3 || echo "cp fail" >> <span class="katex math inline">logfile # 无错误输出
fn_cp</span>src4 <span class="katex math inline">dst4 || echo "cp fail" >></span>logfile 2>&1 # 写得太多,麻烦
}
结合xt,我们可以给出更好的方案
function fn_main() { fn_cp <span class="katex math inline">src1</span>dst1 xt <span class="katex math inline">? `</span>PS8` "cp fail" || return <span class="katex math inline">?}fn_main</span>@ | tee -a <span class="katex math inline">logfileret=</span>PIPESTATUS[0]exit <span class="katex math inline">ret
3. KISS,我们可以使用全局变量
先看一下老代码:
function fn_get_keys_from_conf() { key1=`fn_get_val key1` key2=`fn_get_val key2` key3=`fn_get_val key3`}function fn_proc1() { local key1=</span>1 local key2=<span class="katex math inline">2 local key3=</span>3} . . .function fn_procn() { local key1=<span class="katex math inline">1 local key2=</span>2 local key3=<span class="katex math inline">3}function fn_main() { fn_get_keys_from_conf fn_proc1</span>key1 <span class="katex math inline">key2</span>key3 fn_proc2 <span class="katex math inline">key1</span>key2 <span class="katex math inline">key3 fn_proc3</span>key1 <span class="katex math inline">key2</span>key3}fn_main
变量如果没有local限定词,其属性默认为全局的,使用local局部变量可以使变量
使用更加安全,但是带来大量冗余与重复,导致失误操作增加。
大多时候,从配置文件中读取的配置都是只读的,为了安全,我们只要使用关键字
readonly就可以保证其安全了。而且我们可以把所有全局变量放在一起管理。
那么上面的代码这样就可以了:
function fn_get_keys_from_conf(){ readonly key1=`fn_get_val key1` readonly key2=`fn_get_val key2` readonly key3=`fn_get_val key3`}function fn_main(){ fn_get_keys_from_conf fn_proc1 fn_proc2 fn_proc3}fn_main
后记:使用已有特性DIY解决应用过程中的问题,不断优化,如此才有进步。不断的重复自己,只会让人变懒变傻。
本文链接:http://www.yunweipai.com/796.html
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/53151.html