shell编程之DRY&KISS

用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 ] &amp;&amp; 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" &gt;</span>logfile # 不小心把日志清空了
    fn_cp <span class="katex math inline">src3</span>dst3 || echo "cp fail" &gt;&gt; <span class="katex math inline">logfile # 无错误输出
    fn_cp</span>src4 <span class="katex math inline">dst4 || echo "cp fail" &gt;&gt;</span>logfile 2&gt;&amp;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

(0)
上一篇 2021年8月6日 17:57
下一篇 2021年8月6日 17:57

相关推荐

发表回复

登录后才能评论