定义:
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
规范:
- 在使用变量的时候需要在变量前面增加一个$符(声明和接收不需要$);
- 变量名后面的等号左右不能有空格;
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头,中间不能有空格,可以使用下划线“_”。不能使用bash里的关键字命名;
- 双引号能够识别变量,且能实现转义;单引号不能识别变量,会原样输出,且不能实现转义;
- 当在shell中需要执行一些指令并且将执行的结果赋给变量的时候需要使用
反引号
。
定义变量
- 规范:
- 变量名可以由字母、数字和下划线组成,但不能由数字开头;
- 等号两侧不能有空格;
- 变量名称一般习惯为大写。
- 定义变量:变量=值
- 撤销变量:unset 变量
- 声明只读变量:readonly 变量
- 将命令的返回值赋给变量:
- 方式一:’ ‘
- 示例:A=’ls’
- 方式二:$()
- 示例:A=$(ls)
- 方式一:’ ‘
- 设置环境变量
变量默认的生命周期是在当前进程,而环境变量就像一个全局变量,可以在任何进程使用
- 引用变量:
- 格式:${变量名}
- 查看变量的值:
- 格式:echo ${变量名}
位置参数变量
用于获取到命令行的参数信息的变量。
变量 | 描述 |
---|---|
$n | n 为数字,$0 代表命令本身,$1-$9 代表第一到第九个参数,十以上的参数需要用大括号包含,如${10} |
$* | 代表命令行中所有的参数,它把所有参数看作为一个整体 |
$@ | 也代表命令行中的所有参数,不过它把每个参数区分对待 |
$# | 代表命令行中所有参数的个数 |
变量 | 描述 |
---|---|
$$ | 代表当前进程的进程号(PID) |
$? | 代表最后一次执行的命令的返回状态。如果这个变量的值为 0,证明上一个命令正确执行;如果这个变量的值为非 0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确。 |
环境变量
变量默认的生命周期是在当前进程,而环境变量就像一个全局变量,可以在任何进程使用。
- 定义格式:export 变量名=变量值
- 查看系统所以的环境变量:env
- 配置文件:
加载顺序由前到后,同名变量,后面的会覆盖前面的
- 定义数组
- arr=( 10 23 45 )
- 显示数组中的所有元素
- echo ${arr[@]}
- 显示数组元素个数
- echo ${#arr[@]}
显示数组中的某个元素
三种使用方式:
- $[运算式]
- $((运算式))
- 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 #任务执行完毕