shel脚本l写作技巧与艺术

shell的江湖地位

社会的个体是人,互联网的个体是服务器,有人的地方就有江湖,那么服务器们也形成了江湖,这个江湖很有趣,总是两眼一抹黑,黑漆漆的屏幕,闪烁的光标不停的发出骇人的射线,把心志不坚定的人们赶出去。这导致存在即高手。

东道主

服务器领域中,shell脚本语言无疑是作为任何服务器编程语言的东道主的。所有的编程语言(确切的说是服务端编程语言)都需要使用一定的命令才能形成自己的服务,比如java、javaw、python、npm(nodejs)、gcc等等,他们都是对应编程语言的命令,借助这些命令才能形成程序。任何可以使用的命令,都是shell脚本可以容纳的。shell就是各个编程语言的大管家。

老祖

shell语言诞生的非常之早。可以说第一台具备操作系统的计算机出现的时候,shell就对应存在了(当然,这个shell语言不是Linux shell)。之所以新人会感觉害怕,就是因为这个语言没有良好的人机交互,总给人一种,万一弄错系统就崩溃了。这也反面说明了,越懂操作系统,使用shell就越顺手。正因为如此,江湖有人说:“windows操作系统入门简单,精通难;Linux操作系统入门难,精通容易”。毕竟玩Linux就是直接拿shell开始玩,能玩懂了,这个系统也就懂了。

外星人

如果编程语言是人,shell就是外星人。shell语言灵活,充满个性,想要读懂很难,想要理解其深刻艺术性更难。笔者曾经三次查看MySQL的官方安装文档,每次查看大概间隔一年多左右,随着对Linux的理解加深,每次看得到的收获不一样。shell语言没有捷径,唯有更懂操作系统,多看别人的脚本,不断提升。

shell语言没有捷径,唯有更懂操作系统,多看别人的脚本,不断提升。这句话让你想到了什么?

shell之痒

shell很容易成为孤儿,应该熟练使用它的运维工程师觉得开发脚本是研发工程师的责任,研发工程师觉得自己只是在windows上开发程序而已,和服务器操作系统(通常是Linux的某个发行版)没有一毛钱关系,脚本应该是伺候服务器的运维来写的。总之,到了最后,没人写。

无效的编程思想

shell的函数有调用顺序

shell是一行一行读取执行的,这和JavaScript语言不一样。由于没有整个文件被读取,没有形成抽象语法树,所以没法使用定义在当前行以后的函数。因此,shell脚本中函数和函数之间最好没有什么关系,非要有关系,那就一定是个顺序关系。

shell的变量没有作用域

任何一个函数,只要被执行过后,函数中的变量就会成为类似全局变量的概念,在shell执行到最后一行之前,是一直驻留的,因此,不要随便定义变量,不要随意使用之前函数中出现的变量,避免将来看不懂。

shell的函数没有返回值

不同于其他编程语言,shell函数是没有返回值的,确切的说是没有返回值类型。shell只会返回数字表示成功失败。0成功1失败,通常有人习惯使用exit 指定错误数字。

shell是面向过程的

shell没有类的概念,shell也没有包的概念,通常都是一个文件搞定事情。

作文

正如上文所说,shell语言没有捷径,唯有更懂操作系统,多看别人的脚本,不断提升。这就和我们读书的时候写作文是一样的。作文是一种艺术熏陶的体现。对文学艺术体会的越深刻,手法使用的越多,就越容易让老师感到欣慰,得到高分。

多写不会手生

shell脚本一定要多写,例如if,case之流。它们是少数shell脚本的语法,但是确实交互感很差,所有的语法都有“闭标签”,新手不注意,很容易倒在脚本的错误中。熟练了,怎么写都不会出错。

多看汲取灵感

一定要多看别人的脚本,尤其是大厂的脚本,确实能够让人眼前一亮。工作中我们寻求的是把常用的命令沉淀下来形成脚本,需求是比较简单的,而且没有过多适配性。多看适配性强的代码,也很容易让自己写出高水平的脚本来。

多悟体会艺术

如果只是依葫芦画瓢,做脚本的搬运工是很难再进一步提高的。因为shell太灵活,所以并没有所谓好脚本这个标准。只有自己写出最合适的脚本才是最重要的,因此需要透过代码,看到其内部的艺术感。

shell技巧与艺术赏析

函数框架

#!/bin/bash

set -e

function a(){
}
function b(){
}
function c(){
}
a
b
c
  • set -e 使得脚本报错就停止,这可以避免错误蔓延,降低反向修复的困难。
  • 函数在前,尽量函数之间没有调用关系。
  • 函数框架式脚本是希望将所有的函数执行一遍就可以实现功能,这里体现了代码分块的思想。
  • 最后一个函数,如果有需求,也可以i变成控制器,用来决定如何调用上面的函数。(当然,这种情况,最后就只有一个函数作为入口被调用)。

连续判断取值

PYTHON_HOME="${BASE_DIR}/venv/bin"
[ ! -e "${PYTHON_HOME}/python" ] && PYTHON_HOME=/usr/local/python/bin
[ ! -e "${PYTHON_HOME}/python" ] && PYTHON_HOME=/usr/python/bin
[ ! -e "${PYTHON_HOME}/python" ] && PYTHON_HOME=/opt/python/bin
[ ! -e "${PYTHON_HOME}/python" ] && unset PYTHON_HOME

  • 由于不同发行版的Linux安装软件的默认地址可能不同,配置文件路径也可能不同,因此采用试错的方法,确定配置文件的位置。
  • 如果找到了配置文件,则之后几行的判断结果都为false
  • 如果找不到配置文件,则走到最后,unset变量

短参数

while getopts ":h:a:" opt; do
  case $opt in
  h)
    VAL1=$OPTARG
    ;;
  a)
    VAL2=$OPTARG
    ;;
  ?)
    echo "Unknown parameter,you can use home|action parameter"
    exit 1
    ;;
  esac
done
  • 支持脚本使用时传入短参数,例如 sh xxx.sh -h help -a action,则最后VAL1变量值为help,VAL2值为action

技巧

取随机数
# n为数字,数字越大,生成的随机数则越大
openssl rand -base64 n 

前提是安装openssl,因为几乎都有安装,倒也不是大问题,但建议使用yum -y install openssl检查一下。

文件备份
date +%m-%d-%y_%_H:%M:%S

文件备份中使用日期命令,让最后形成的备份文件名有一定的直观含义。

写配置文件
cat << EOF > xxx.conf
...
EOF

基于配置文件内容不适合局部替换,需要大量重写或者追加(> xxx.conf 改为 >> xxx.conf),这种方法比复杂的sed效果要好

判断上一步操作是否成功
if [ $? -eq 0 ]; then
     echo "succeed"
else
     echo "failed"
fi

Linux没有消息就是好消息,错误消息其执行返回值不等于0.利用这个特性,我们可以大胆通过试错来得到我们想要的结果.需要注意要把错误输出写到null设备中。

id ${APP_USER} >& /dev/null
if [ $? -eq 0 ]; then
     echo "系统中已经存在nginx用户"
else
     useradd -M -s /sbin/nologin ${APP_USER}
fi
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值