1.函数格式
- 目的:将一些相对对立的代码变成函数,提供可读性和重用性,避免重复编写相同代码。
- 函数格式:
- 显式返回:加return,return后面接数值n(0~255);
- 隐式返回:最后一个命令的运行结果;
- 函数关键字:function可以省略,可不带任何参数;
- 符号{表示函数体的开始(可在函数名后单独一行),符号}表示函数体结束;
- 函数返回值:
[function] 函数名 [(参数列表)] { commands; [return int;] }
2.函数调用
- 调用函数名:所有函数必须在使用前预先定义好,即函数放在脚本文件的开始位置,调用函数时仅使用函数名即可。
#! /bin/bash foo () { echo "This is foo" return 0 } foo # 调用函数foo()
3.shell中的函数参数
- 在shell中,调用函数时可以向函数传递参数。在函数内部取参数时,通过特殊变量$n的形式来获取参数的值。函数调用时,通过命令行参数的形式来传递参数。
[cdl@h3c/home/cdl/Test]$cat demo.sh #!/bin/bash :<<comment echo "这是shell脚本中整段代码注释的方法,不需要逐行用#进行注释" comment printFunParams() { echo "当前文件名称: $0" echo "命令行参数中的第1个参数: $1" echo "命令行参数中的第2个参数: $2" echo "传递给脚本或函数的所有参数: $@" echo "传递给脚本或函数的所有参数: $*" echo "传递给脚本或函数的所有参数总数: $#" } # 调用带参数的函数 printFunParams A B C D [cdl@h3c/home/cdl/Test]$./demo.sh 当前文件名称: ./demo.sh 命令行参数中的第1个参数: A 命令行参数中的第2个参数: B 传递给脚本或函数的所有参数: A B C D 传递给脚本或函数的所有参数: A B C D 传递给脚本或函数的所有参数总数: 4
4.shell编程规范
(1).脚本文件名称以.sh结尾,尽量使用UTF-8文件编码;
(2).脚本文件首行使用#!/bin/bash,没有空格,不带任何选项;
(3).程序头注释:脚本功能、作者、修改时间等;
(4).全局变量定义在程序头注释后空一行开始位置,尽量大写;
(5).变量的引用使用${var},不推荐使用$var;
(6).单引号(推荐常量)、双引号(推荐变量)、不用引号(推荐数字);
(7).数值运算let和(())中的变量不要加$、expr中加$;
(8).成对符号尽量一次性写完,防止遗漏,如:{}、[]、"";
(9).[]或[[]]两端有空格;
(10).命令替换,推荐${cmd}形式,不推荐`cmd`格式;
(11).脚本代码缩进没有强制要求,要么统一用空格或TAB键;
(12).关键操作给一个执行结果状态,执行失败时exit N(前一个命令执行状态结果,使用$?来检查);
(13).关键操作需要日志记录,记录操作的成功、失败及操作时间;
(14).可以使用&&、|| 代替简单的if-then-else-fi语句;
(15).命令过长时使用符合\来延长,有管道的命令时除外;
(16).尽量使用函数功能,将不同功能定义为不同函数,直接调用函数;
(17).文件名全部小写命名,禁止使用rm -rf *
(18).分离复合命令(if分支结构、for/while循环),尽量使用如下形式:
if [ 条件 ]; then ...... fi while true; do ...... done for value in {1...10}; do ...... done
5.shell脚本的调试
- (1).调试跟踪(sh -x 脚本文件名)
- shell脚本文件调试的首选方法,进入调试模式后shell会依次执行语句,产生调试信息(带加号表示该语句是shell执行的,不带加号表示是shell产生的输出)
[cdl@h3c/home/cdl/Test]$sh -x demo.sh + : + printFunParams A B C D + echo '当前文件名称: demo.sh' 当前文件名称: demo.sh + echo '命令行参数中的第1个参数: A' 命令行参数中的第1个参数: A + echo '命令行参数中的第2个参数: B' 命令行参数中的第2个参数: B + echo '传递给脚本或函数的所有参数: A' B C D 传递给脚本或函数的所有参数: A B C D + echo '传递给脚本或函数的所有参数: A B C D' 传递给脚本或函数的所有参数: A B C D + echo '传递给脚本或函数的所有参数总数: 4' 传递给脚本或函数的所有参数总数: 4
- (2).检查语法(sh -n 脚本文件名)
- 对脚本文件进行语法检查,但是不执行脚本。如果存在语法错误,shell会报错。如果没有错误,则不显示任何内容。
[cdl@h3c/home/cdl/Test]$cat demo.sh #!/bin/bash :<<comment echo "这是shell脚本中整段代码注释的方法,不需要逐行用#进行注释" comment printFunParams() { echo "当前文件名称: $0" echo "命令行参数中的第1个参数: $1" echo "命令行参数中的第2个参数: $2" echo "传递给脚本或函数的所有参数: $@" echo "传递给脚本或函数的所有参数: $*" echo "传递给脚本或函数的所有参数总数: $#" # 调用带参数的函数 printFunParams A B C D [cdl@h3c/home/cdl/Test]$sh -n demo.sh demo.sh: line 22: syntax error: unexpected end of file
- (3).trap语法(信号捕捉)
- DEBUG信号跟踪分析相关变量值的变化;
- 脚本程序被中断时完成清理工作;
- 询问用户是否终止该脚本运行;
- trap命令用于指定在接收到信号signal(SIGHUP、SIGINT、SIGQUIT、SIGKILL、SIGTERM等)后要执行command命令。常见用法:
- (4).tee语法(管道复制 tee -a 文件名)
- tee命令用于读取标准输入的数据,并将其内容输出到文件中,即输出给屏幕和指定文件。例如: ls -l tee file.txt | less