目录
Shell脚本
概念
- 将要执行的命令按顺序保存到一个文本文件
- 给该脚本文件可执行权限
- 可结合各种Shell控制语句以完成更复杂的操作
执行命令流程的交互区别
交互式
- 用户直接与命令行交互,实时输入和接收命令行程序的输出
非交互式
- 命令在执行时按照脚本文件中预先定义好的指令顺序执行,并且通常不会从用户终端获取输入
- Shell脚本执行的流程就是非交互式
Shell脚本应用场景
- 重复性操作
- 交互性任务
- 批量事务处理
- 服务运行状态监控
- 定时任务执行
- 巡检
Shell的作用
Shell的作用 —— 命令解释器,“翻译官”
- 介于系统内核与用户之间,负责解释命令行,解释的结果发送给内核,内核再向硬件发送指令。
- 每个操作系统都可以支持多个不同的解释器
- 每个系统的解释器不一定支持相同的脚本
列出系统中全部解释器
CentOS系统默认的解释器就是bash
实验
脚本的基本书写格式和执行命令
新建并编辑一个脚本文件
#!/bin/bash:声明,只有写在第一行才生效,如果写在其他行就变成注释的作用,告诉系统执行该脚本只能用bash解释器来解释
按照执行顺序编写如下语句,像 ll 这种使用别名的命令在脚本中是不识别的,所以使用 ls -l
保存并退出
在子bash下执行脚本
先打开一个子bash,然后执行脚本,执行完再退出子bash
相当于运行了一遍如下步骤
为了更好理解bash命令,看下图
指定解释器的方式执行脚本
使用bash命令执行脚本文件,如果通过指定解释器的命令执行脚本文件就可以不在脚本文件内容中加入声明(#!/bin/bash)
使用 sh 命令指定sh解释器执行脚本,虽然解释器名称不同,但是sh在CentOS 7系统中是bash解释器的软链接
指定路径方式执行脚本
需要拥有被执行脚本的执行权限
相对路径
直接输入脚本文件的相对路径来执行脚本
并使用chmod命令添加执行权限
绝对路径
直接输入脚本文件的绝对路径来执行脚本
直接加载脚本
在当前解释器下直接执行脚本
使用 . 脚本文件 或 source 脚本文件 来执行脚本,但是执行方式是有区别的,
将脚本修改为如下,增加echo命令和注释,更方便管理者使用,保存并退出
结果
重定向
重新定义输出的方向
- 尖括号往右指是重定向标准输出 >、>>
- 尖括号往左指是重定向输入
覆盖输出
使用echo命令实现本该输出在终端的信息输出进文件中
重定向输出 ls 内容,还覆盖了上一次重定向的内容(nihao)
追加输出
使用>>两个尖括号追加内容到指定文件
重定向输入
输出新建一个存放密码的文件
新建一个用户
比如修改一个用户的密码,通过passwd的--stdin选项,指定标准输入的设备,默认设备是键盘,这里指定为文件,就将密码设为文件中的字符串了
前提是关闭内核安全机制
通过脚本实现
新建脚本文件
将要执行的命令添加进脚本
此时执行该脚本
错误重定向
把提示的错误信息单独提取出来放入文本中
- 标准输出:1>
-
- 正常信息输出到指定文件,错误信息在终端显示
- 错误输出:2>
- 正常信息在终端显示,错误信息输出到指定文件中
- 标准输出和错误输出同时重定向:&>
- 正常信息和错误信息都输出到指定文件中
比如在检测一个源码软件包所需依赖时
使用 ./configure 2> error.log 命令
管道符
作用:过滤
比如要只查看根分区的挂载信息
使用 df 命令并通过管道符过滤
- $符在文本前表示以文本开头:grep "$text"
- $符在文本后表示以文本结尾:grep "text$"
相关命令
命令 |
说明 |
df -h | grep "d" |
显示df命令输出的内容中包含 "d" 的行 |
df -h | grep "/$" |
显示df命令输出的内容中以 " / " 结尾的行 |
df -h | grep "/$" | awk '{print $6}' |
显示df命令输出的内容中以 " / " 结尾的行中的第6列 |
grep "root" /etc/passwd | grep "bash" |
显示/etc/passwd文件内容以root开头bash结尾的行 |
变量
变量是用于存储数据值的名称
变量一般存放在内存中,所以当重启主机后,没有文件保存的变量会消失
取消变量
使用unset命令取消变量
命名规则
- 变量名只能由字母、数字和下划线组成,但不能以数字开头(或纯数字)。
- 变量名=值
变量赋值
复制name变量的值为zhangsan,并使用 echo $变量名 来输出变量的值
echo命令还可以连续输出变量
或使用大括号,区分变量的边界
将name变量的值赋值给NewName变量
引号
- 如果声明字符串,并且字符串中带有空格的情况下,要加引号
- 如果要声明数字,就不能加引号
如果使用双引号来定义变量,写在变量内带$符的字符串也会被识别为变量
如果使用单引号来定义,变量内带$符的字符串不会被识别为变量
并且两个引号是可以互相嵌套的,单引号和双引号可以互相嵌套,但是一种引号不能自己嵌套自己
反撇号 `
如果要在变量中加入命令,要用反撇号包起来
将反撇号内命令输出的结果作为开头 ls -l 命令的参数执行
使用$()嵌套命令
如果要输入嵌套多层的命令就要使用$()把内容包起来
查找并显示 useradd 命令所属的RPM包,并列出该RPM包中的所有配置文件路径
交互式变量声明
使用 read 命令交互声明name变量
加入 -p 选项 定义num变量的值为输入值
作用范围
局部变量
只会在当前解释器内生效的变量
当声明完一个变量后,默认为局部变量,只会在本Shell下生效,进入一个子bash环境会找不到该变量
因为这样声明的变量是局部变量,只针对本Shell解释器
全局变量
在每一个解释器内都生效的变量
使用export命令导出指定变量为全局变量
也可以在声明变量时直接设置为全局变量
永久保存变量
上面所声明的变量在reboot重启后就会消失
通过编辑 全局变量文件 来将变量写入到文件中
在文件末尾添加变量,保存并退出
使用 source 命令执行该文件 或 重启主机,就可以看到变量已经被声明了
数字变量操作
定义两个值为数字的变量,通过expr命令得出运算结果(expr只能计算整数)
因为 *是同通配符,所以通过 \ 转义符 + * 来计算乘法运算
除法运算和取余运算
通过$()嵌套运算
变量查看
命令 |
说明 |
env |
列出全局变量 |
set |
列出当前Shell中的所有变量 |
特殊变量
编写一个脚本文件,编写内容如下
使用bash命令添加两个值来执行该脚本
由此可见,$1和$2的作用可以理解为占位符
$#
显示参数的数量
$*
执行该脚本,可以看到作用是显示添加的参数
$@
echo $@的作用是将所有位置参数作为单独的字符串显示,而不是像echo $* 变量整理为一整个字符串
echo $*
10 20 30
"$1 $2 $3"
echo $@
10 20 30
"$1" + "$2" + "$3"
$0
输出当前的脚本 绝对 / 相对路径
$!和$$
- $!:上一个进程的进程号
- $$:当前进程号
$?
检查上一个指令执行的结果状态
echo $?
如果状态正常就返回0
如果状态不正常就显示非0