定义:
Shell 是一个命令行解释器,它为用户提供了一个向 Linux 内核发送请求以便运行程序的界面系统级程序,用户可以用 Shell 来启动、挂起、停止甚至是编写一些程序。
注释:

  • 单行注释:#
  • 多行注释::<<!注释内容!

编写规范:

  • 代码规范:所有的shell脚本首行必写 #!/bin/bash
  • 命名规范:文件名.sh

shell执行:

  • 方式一:使用系统自带的shell来解释执行
    • 格式:bash 脚本路径(/bin/bash 的快捷方式)
  • 方式二:使用sell脚本文件中第一行指定的shell环境来解释执行
    • 格式:脚本路径
    • 运行当前目录下的test.sh时,一定不要写成test.sh,而是写成./test.sh,或者写绝对路径也行。
      为什么不能写成test.sh去执行呢?因为直接写成test.sh,系统会去PATH(环境变量)中寻找,其实运行其它二进制程序也是如此。
    • 如果第一行没有指定执行的shell环境,则通过用户的$SHELL环境变量指定的那一个shell来执行。
  • 方式三:不产生子进程执行shell
    • 格式:source ./shell.sh
    • 格式二:. shell.sh
    • 方式一和方式二会产生子进程来执行shell,因此对当前进程无影响;而方式三,就在当前进程执行,是不会产生子进程的。

常用命令:

命令 描述
bash -v 脚本 检查脚本中的语法错误
bash -x 脚本 查看脚本执行的详细过程

变量

显示当前shell中所有变量:set

规范:

  1. 在使用变量的时候需要在变量前面增加一个$符(声明和接收不需要$);
  2. 变量名后面的等号左右不能有空格;
  3. 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头,中间不能有空格,可以使用下划线“_”。不能使用bash里的关键字命名;
  4. 双引号能够识别变量,且能实现转义;单引号不能识别变量,会原样输出,且不能实现转义;
  5. 当在shell中需要执行一些指令并且将执行的结果赋给变量的时候需要使用 反引号

定义变量

  • 规范:
    1. 变量名可以由字母、数字和下划线组成,但不能由数字开头;
    2. 等号两侧不能有空格;
    3. 变量名称一般习惯为大写。
  • 定义变量:变量=值
  • 撤销变量:unset 变量
  • 声明只读变量:readonly 变量
  • 将命令的返回值赋给变量
    • 方式一:’ ‘
      • 示例:A=’ls’
    • 方式二:$()
      • 示例:A=$(ls)
  • 设置环境变量

变量默认的生命周期是在当前进程,而环境变量就像一个全局变量,可以在任何进程使用

  • 格式:export 变量名=变量值

    引用变量

  • 引用变量
    • 格式:${变量名}
  • 查看变量的值
    • 格式:echo ${变量名}

其中的{}可以省略

位置参数变量

用于获取到命令行的参数信息的变量。

变量 描述
$n n 为数字,$0 代表命令本身,$1-$9 代表第一到第九个参数,十以上的参数需要用大括号包含,如${10}
$* 代表命令行中所有的参数,它把所有参数看作为一个整体
$@ 也代表命令行中的所有参数,不过它把每个参数区分对待
$# 代表命令行中所有参数的个数
  • 动态替换
    1. #当位置变量1为空的时候,用null值替换
    2. var=${1-null}

    预定义变量

    就是 shell 设计者事先已经定义好的变量,可以直接在 shell 脚本中使用。
变量 描述
$$ 代表当前进程的进程号(PID)
$? 代表最后一次执行的命令的返回状态。如果这个变量的值为 0,证明上一个命令正确执行;如果这个变量的值为非 0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确。

环境变量

变量默认的生命周期是在当前进程,而环境变量就像一个全局变量,可以在任何进程使用。

  • 定义格式:export 变量名=变量值
  • 查看系统所以的环境变量:env
  • 配置文件:

加载顺序由前到后,同名变量,后面的会覆盖前面的

  • /etc/profile
  • ~/.bash_profile
  • ~/.bashrc
  • /etc/bashrc

    数组

  • 定义数组
    • arr=( 10 23 45 )
  • 显示数组中的所有元素
    • echo ${arr[@]}
  • 显示数组元素个数
    • echo ${#arr[@]}
  • 显示数组中的某个元素

    • echo ${arr[n]}

      运算符

  • 三种使用方式

    • $[运算式]
    • $((运算式))
    • expr m + n

注意:expr运算符间要有空格,且shell仅支持整数运算

运算符 描述
算数运算符 + - \* / % 加、减、乘、除、取余,因为*是通配符,所以需要转义
关系运算符 -lt -le -eq -gt -ge -ne 小于、小于等于、等于、大于、大于等于、不等于
逻辑运算符 ! -O -a 非、或、与
字符串运算符 = != -z -n 字符串相等、不等、长度是否为0、是否不为0
文件测试运算符 -r -w -x 读、写、执行
-e -f -d -s 文件存在、常规文件、目录、检测文件是否不为空

流程控制

判断条件

test命令用于检查文件或则比较值;通过$?可以查看test命令是否正确,正确返回0,错误返回非零。

  • 其实判断条件就是基于test命令来实现的,它将test命令简化为 []符号
  • []符号还有扩展写法[[]] 以支持&、&、||、<、>
  • [ condition ],注意,condition前后一定要加空格。

if

#语法一:
if [ condition ];then
    程序
fi

#单行模式:
if [ condition ]; then 程序;fi

#语法二:
if [ condition ];then
  程序1
else
  程序2
fi

#语法三:
if [ condition ];then
  程序1
elif [ condition ];then
  程序2
else
  程序n
fi

#语法四:
if [ condition ];then
    程序1
  if [ condition ];then
      程序2
  fi
fi

case

case $变量名 in
"值 1")
   command1
   ;;
"值 2")
   command2
   ;;
...
*)
   finalCommand
   ;;
esac

for

#语法一:
for 变量 in 值1 值2 值3…
do
  程序
done

#语法二:
for((初始值;循环控制条件;变量变化))
do
  程序
done

while

while [ condition ]
do
  程序
done
  • until循环:将while关键字换为until即可,与while相反,当condition为true时,停止循环

函数

系统函数

  • 系统自建函数库
    • /etc/init.d/functions
  • 使用
    • 使用 source 函数脚本文件 将函数库中的函数导入当前的shell运行环境后,就可以直接使用函数了

自定义函数

  • 基本语法

    function fName(){
     函数体
     return xxx;
    }
    
  • 说明

    • function关键字可省略;
    • () 内不用写任何东西,可通过位置参数变量来获取参数;
    • 在函数体中可通过local关键字来修饰变量,使其该变量只是在函数中有效。
    • 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
  • 示例

计算输入两个参数的和

function getSum(){
    SUM=$[$n1+$n2]
  echo "等于:$SUM"
}

交互编程

读取控制台输入

  • 语法:
  • read [options] 变量
    -p:指定读取值时的提示符;
    -t:指定读取值时等待时间(秒),如果没有在指定时间内输入,就不等待了。
  • 示例 ```shell

    示例1:读取控制台输入一个num值

    read -p “请输入一个数num1=” NUM1 echo “你输入的值是num1=$NUM1”

示例2:读取控制台输入一个num值,在10s内输入

read -t 10 -p “请输入一个数num2=” NUM2 echo “你输入的值是num2=$NUM2”


<a name="2t1gV"></a>
## Expect
Expect编程工具语言,用来实现自动和交互式任务进行通信。<br />注意:该脚本要能执行需要安装expect的运行环境:yum install -y expect

- **常用命令**:
| **命令** | **说明** |
| :---: | :---: |
| spawn | 启动脚本和命令的会话 |
| expect | 从进程接收指定的变量名的字符串 |
| send | 接收一个字符串参数,并将该参数发送到进程 |
| send_user | 用于打印输出,相当于shell中的echo |
| set | 设置变量 |
| interact | expect进程结束后,允许用户继续交互,而不是直接退出 |
| eof | 标识子进程已结束,expect脚本退出 |


- **示例:**
   - 自动远程登录脚本
```shell
#iterm2远程连接自己服务器配置文件
set user root
set host 101.132.163.141
set password 123456
set port 22
spawn ssh -p $port $user@$host    #开启新expect进程,并执行ssh命令
expect "Password:"                            #进程返回"Password:" 时
send "$password\r"                            #向进程输入变量$password 的值 123456
interact                                                #
expect eof                                            #任务执行完毕