在日常工作中,是不是觉得shell脚本就是一堆命令;很多时候他们只是为了实现功能而没有良好的组织结构;你不想再读你自己的剧本;哈哈,我来教shell的《葵花宝典》。从此,你的shell脚本就拥有了和python一样的美,而且非常容易维护。停止编写shell脚本真的是不可能的。现在以nginx控制脚本为例,一起来看看脚本的美化过程:#!/bin/bash#set命令的精彩使用在文末留下set-eu#nginxoverloads配置文件nginx-c/etc/nginx/nginx.confconf-tkill-HUP`psauxf|grep-E"nginx:[[:space:]]+master"|awk'{print$2}'`书本和秘籍的变量在脚本中提取,需要依赖外部配置,如配置文件的位置、监听端口等可变参数,在编程时需要单独放入变量中。为了更好的参考和维护,省去了一项一项修改外部配置的麻烦。#!/bin/bash#set命令的精彩使用留到文末。set-eu#nginx配置文件在不同环境下可能位置不同,所以需要提取到可配置变量中,脚本引用NGINX_CONFIG_FILE=/etc/nginx/nginx.conf#nginx重载配置文件nginx-c$NGINX_CONFIG_FILE-tkill-HUP`psauxf|grep-E"nginx:[[:space:]]+master"|awk'{print$2}'`book毕竟秘籍的模块化运维不是专业的程序员。写剧本的时候有多舒服。简单来说就是从上到下顺序执行,导致复用性差,维护困难。解决这个问题的关键在于函数化,模块化的思维,shell虽然是一门比较简单的语言,但是它具有基本的逻辑控制和函数式功能,这让我们可以写出具有无限可能的高质量的shell脚本。接下来我们来看具体的例子来感受一下:#由于nginx配置文件检查是执行其他操作的第一步,所以我们将其单独分离成一个单独的函数#!/bin/bash#set的妙用命令留在文末set-eu#nginx配置文件在不同的环境下可能位置不同,所以需要抽取成一个可配置的变量,脚本会参考NGINX_CONFIG_FILE=/etc/nginx/nginx.confconf#提取配置文件并作为一个单独的Functionconfig_test(){nginx-c$NGINX_CONFIG_FILE-t}get_nginx_master_pid(){echo`psauxf|grep-E"nginx:[[:space:]]+master"|awk'{print$2}'`}#Extraction配置重载是一个独立的函数reload(){kill-HUP`get_nginx_master_pid`}#nginx重载配置文件config_testreloadmain函数脚本的可维护性取决于脚本的结构。为了有一个更好的结构,通常需要在脚本中定义入口函数,即main函数,这样我在维护脚本的时候就可以更好的掌握脚本的组织结构和找到入口:#因为nginx配置文件检查是执行其他操作的第一步,所以我们将它单独分离成一个单独的函数#!/bin/bash#set命令的精彩用法留在文末。set-eu#nginx配置文件在不同的环境下可能有不同的位置,所以需要将其抽取成一个可配置的变量。脚本引用NGINX_CONFIG_FILE=/etc/nginx/nginx.conf#将配置文件提取到一个单独的函数config_test(){nginx-c$NGINX_CONFIG_FILE-t}get_nginx_master_pid(){echo`psauxf|grep-E"nginx:[[:space:]]+master"|awk'{print$2}'`}#提取配置重载到独立函数reload(){kill-HUP`get_nginx_master_pid`}#入口函数main(){config_testreload}#mainin这个需要获取脚本本身的参数,所以将$@传递给主函数main$@秘籍书的函数返回值在其他编程语言中,可以通过return获取函数的返回值返回值,但return语句在shell中具有不同的含义。return命令将返回一个函数并返回一个数字参数,这个数字参数在调用这个函数的脚本中是可见的。如果没有指定return参数,return在默认情况下,会返回上一条命令的返回码。如何实现类似其他编程语言的返回效果?可以使用echo命令:#!/bin/bashset-euNGINX_CONFIG_FILE=/etc/nginx/nginx.confconfig_test(){nginx-c$NGINX_CONFIG_FILE-t}#这里可以直接使用nginx的masterpid获取后的值echoget_nginx_master_pid(){echo`psauxf|grep-E"nginx:[[:space:]]+master"|awk'{print$2}'`}reload(){#`get_nginx_master_pid`获取nginxmasterpidkill-HUP`get_nginx_master_pid`}#入口函数main(){config_testreload}#main这里需要获取脚本本身的参数,所以通过$@给主函数main$@宝书外书之set命令。bash中内置的set命令可以改变我们脚本的执行行为,让我对脚本的掌握和调试更加得心应手。下面是一些常用的set命令,相信你会喜欢的:set-e:bash脚本遇到错误立即退出set-n:检查脚本语法但不执行set-u:遇到未设置的变量并立即退出exitsset-opipefail:管道字符执行过程中如果出现错误则控件立即退出set-x:分步调试命令在写脚本的时候,我们可以直接在脚本的开头简写为以下格式:#!/bin/bashset-euxopipepefail检查bash脚本的语法时,可以这样写:bash-nmain.sh
