B站视频《2020全新shell脚本从入门到精通实战教程》笔记
视频链接:https://www.bilibili.com/video/BV1j541157Sr?p=29
这个老师特别搞笑,强烈推荐
一、shell介绍
1.shell介绍:什么是shell?
shell是一个程序,用C语言编写,是用户和linux内核沟通的桥梁。它既是一种命令语言,又是一种解释性的编程语言。
shell讲用户的指令翻译为二进制,传给内核处理。
2.shell功能
*命令行解释功能
*启动程序
*输入输出重定向
*管道连接
*文件名置换
*变量维护
*环境控制
*shell编程
二、shell脚本语法
shell脚本就是将完成一个任务的所有命令按照执行的先后顺序,自上而下的写入到一个文本文件中,然后给予执行权限。
1.如何书写shell脚本
*shell脚本的命名:名字要有意义,建议用.sh结尾,建议不要太长
*shell脚本的格式:
**shell脚本的开头必须指定脚本运行环境以 #! 这个特殊符号来组成。例如:#!/bin/bash 指定该脚本的运行解析由/bin/bash来完成的。
**shell 脚本中的注释使用#号。
**shell脚本中最好加入说明字段 #Author #Script Description
2.shell脚本运行方法
脚本运行需要执行权限,当我们给一个文件赋予执行权限后,该脚本可以运行。
chmod u+x filename
如果不希望赋予脚本执行权限,可以使用bash 命令来运行未给予执行权限的脚本
bash filename
3.shell中的符号
不要和正则表达式中的符号含义搞混
~ :家目录
! :执行历史命令 !!执行上一条命令
$ :变量中取内容符
+ -*/% :对应数学运算 加 减 乘 除 取余数
& :后台执行
* :星号是shell中的通配符 匹配所有
? :问号是通配符 匹配除回车以外的一个字符
; :分号可以再shell中一行执行多个命令,命令之间用分号隔开
| :管道符 上一个命令的输出作为下一个命令的输入
\ :转义字符
`` :反引号 命令中执行命令
'' :单引号 脚本中字符串要用双引号,单引号不解释变量
"" :双引号 脚本中出现的字符串可以用双引号引起来
4.shell管道
| 管道符在shell中使用是最多的,很多组合命令都要通过管道符来完成输出,管道符其实就是上一个命令的输出作为下一个命令的输入
5.shell重定向
> 重定向输入 覆盖原数据
>> 重定向追加输入 在原数据的末尾添加
< 重定向输出
<< 重定向追加输出
6.shell脚本中的数学运算
expr 命令:只能做整数运算,格式比较古板,注意空格
[root@baism ~]# expr 5 - 2
3
[root@baism ~]# expr 5 \* 2 #注意*出现应该转移,否则认为是通配符
3
bc 计算器处理浮点运算,scale=2代表小数点保留两位
[root@baism ~]#echo "scale=2;100/3"|bc
33.33
双小圆括号,在shell中也可以用来做数学运算
[root@baism ~]#echo ((100+3))
103
7.脚本退出
exit NUM 退出脚本,NUM代表一个正数,代表返回值。
三、格式化输出
- echo命令
- 颜色输出
一个程序需要有0个或以上输入,一个或更多输出
1.echo命令介绍
功能:将内容输出到默认显示设备
echo命令的功能是在显示器上显示一段文字,起到一个提示的作用。功能说明:显示文字。
语法
echo [-ne][字符串]
补充说明:echo会将输入的字符串送往标准输出。输出的字符串间以空白字符串隔开,并在最后加上换行号。
命令选项:
-n 不要在最后自动换行
-e 若字符串中出现以下字符,则加以特殊处理,而不会将他们当做一般文字输出。
转义字符:
\a 发出警告声
\b 删除前一个字符
\c 最后不加上换行符
\f 换行但光标仍旧停留在原来的位置
\n 换行且光标移动至行首
\r 光标移至行首,但不换行
\t 插入tab
\v 与\f相同
\nnn 插入nnn(八进制)所代表的ASCII字符
-help 显示帮助 -version 显示版本信息
2.颜色代码
脚本中echo显示内容带颜色显示,需要用参数—e;格式如下
echo -e "\033|字背景颜色;文字颜色m字符串\033[0m"
太多了不抄了
四、格式化输入
read命令
1.read命令
默认接受键盘的输入,回车符代表输入结束
read命令选项
-p 打印信息
-t 限定时间
-s 不回显
-n 输入字符个数
五、shell变量
1.变量介绍
在编程中,我们总有一些数据需要临时存放在内存,以待后续使用时快速读出。
讲义上还有变量存储的原理,这里不展开讲。
2.变量分类
1.本地变量:用户私有变量,只有本地用户可以使用,保存在家目录下的.bash_profile、.bashrc文件中
2.全局变量:所有用户都可以使用,保存在/etc/profile、/etc/bashrc文件中
3.用户自定义变量:用户自定义,比如脚本中的变量
3.变量管理
1)变量定义
变量格式:变量名=值
在shell编程中,变量名和等号之间不能有空格。
变量名命名规则:
命名只能使用英文符,数字和下划线,首个字符不能以数字开头
中间不能有空格,可以使用下划线
不能使用标点符号
不能使用bash里面的关键字
例如VAR1=1
注意:字符串要用单引号或双引号引起来
[root@baism ~]# name="baism"
2)读取变量内容
读取变量内容符:变量名
变量内容读出
[root@baism ~]# echo $name
baism
3)取消变量unset
[root@baism ~]# unset name
4)定义全局变量 export
[root@baism ~]# export name="baism"
备注:上述的变量其实都是一次性变量,系统重启就会丢失
如果希望本地变量或者全局变量可以永久使用,可以将需要设置的变量写入变量文件即可。
5)定义永久变量
- 本地变量:用户私有变量,只有本地用户可以使用,保存在家目录下的.bash_profile、.bashrc文件中
- 全局变量:所有用户都可以使用,保存在/etc/profile、/etc/bashrc文件中
六、shell数组
1.数组介绍
一个变量只能存储一个值,但是现实中又有很多的值需要存储,而数组可以一次存储多个变量。
2.基本数组
数组可以让用户一次赋予多个值,需要读取数据时只需要通过索引调用就可以方便读取出来。
1)数组语法
数组名称=(元素1 元素2 元素3 ...)
2)数组读出
${数组名称[索引]}
索引默认是元素在数组中的排队编号,默认第一个从e开始
3)数组赋值
方法一:一次赋一个值
array1[0]='tom'
方法二:一次赋多个值
array2=(tom jack alice)
4)查看数组
declare -a
declare -a array2='([0]="tom" [1]="jack" [2]="alice")'
5)访问数组元素
#echo $(array1[0]) 访问数组中的第一个元素
#echo $(array1[@]) 访问数组中的所有元素,等同于 echo ${array1[*]}
#echo $(#array1[@]) 统计数组元素的个数
#echo $(!array1[@]) 获取数组元素的索引
#echo $(array1[@]:1) 从数组下标1开始
#echo $(array1[@]:1:2) 从数组下标1开始,访问两个元素
6)遍历数组
默认数组通过数组元素的个数进行遍历
方法二:针对关联数组可以通过数组元素的索引进行遍历
3.关联数组
关联数组可以允许用户自定义数组的索引,这样使用起来更加方便、高效。
3.1) 定义关联数组
申明关联数组变量
declare -A ass_array1
3.2) 关联数组赋值
方法一:一次赋一个值
数组名称[索引]=变量值
ass_array1[index]=pear
方法二:一次赋多个值
#ass_array2=([index1]=tom [index2]=jack [index3]=alice)
3.3)查看数组
declare -A
declare -A ass_array1='([index4]="peach" [index1]="pear" [index3]="orange")'
3.4)访问数组元素
# echo ${ass_array2[index2]} 访问数组中的第二个元素
# echo ${ass_array2[@]}访问数组中的所有元素
# echo ${#ass_array2[@]} 统计数组元素的个数
# echo ${!ass_array2[@]} 统计数组元素的索引
3.5) 遍历数组
通过数组元素的索引进行遍历,针对关联数组可以通过数组元素的索引进行遍历
七、shell五大运算
7.1)数学比较运算
运算符解释
-eq 等于
-gt 大于
-lt 小于
-ge 大于或等于
-le 小于或等于
-ne 不等于
7.2) 字符串比较运算
运算符解释,注意字符串一定别忘了用引号引起来
== 等于
!= 不等于
-n 检查字符串的长度是否大于0
-z 检查字符串的长度是否为0
7.3) 文件比较与检查
-d 检查文件是否存在且为目录
-e 检查文件是否存在
-f 检查文件是否存在且为文件
-r 检查文件是否存在且可读
-s 检查文件是否存在且不为空
-w 检查文件是否存在且可写
-x 检查文件是否存在且可执行
-o 检查文件是否存在且被当前用户拥有
-G 检查文件是否存在且默认组为当前用户组
file1 -nt file2 检查file1 是否比file2新
file1 -ot file2 检查file1 是否比file2旧
7.4) 逻辑运算
逻辑与运算 &&
逻辑或运算 ||
逻辑非运算 |
注意事项:逻辑与 或运算都需要两个或以上条件,逻辑非运算只需要一个条件
7.5) 赋值运算
= 赋值运算 a=10
八、流程控制
8.1 if 语法
8.1.1 语法一:单if语句
适用范围:只需要一步判断,条件返回真干什么 、假干什么。
语句格式
if [condition] #condition值为true 或 false
then
commands
fi
8.1.2 语法二:if-then-else 语句
适用范围:两步判断,条件为真干什么,条件为假干什么
if [condition]
then
commands1
else
commands2
fi
8.1.3 语法三:if-then-elif 语句
适用范围 多于两个以上的判断结果,也就是多于一个以上的判断条件
if [condition 1]
then
commands1
elif [condition 2]
then
commands2
......
else
commandsx
fi
8.1.4 if 高级应用
1.条件符号使用双小圆括号,可以再条件中植入数学表达式
2.使用双方括号,可以在条件中使用通配符
8.2 for循环(循环控制 sleep\continue \ break)
8.2.1 for 循环介绍
很多人把for循环叫做条件循环,for的循环次数和给予的条件是成正比的。
8.2.2 for语法
8.2.2.1 for语法一
for var in value1 value2 value3 ....
do
commands
done
seq是一个数数的语句,seq 1 9 就是从1数到9
8.2.2.1 for语法二
C式的for命令
for ((变量;条件;自增减运算))
do
代码块
done
for还能循环使用多个变量,举例
for ((a=0,b=9;a<10;a++,b--))
do
echo $a $b
done
8.3 循环控制语句
8.3.1 sleep N 脚本执行到该步休眠N秒
8.3.2 continue 跳过循环中的某次循环
8.3.3 break 跳出循环继续执行后续代码
8.4 while循环语句
8.4.1 while循环介绍
什么时候用for,什么时候用while?
知道循环多少次就用for 不知道循环多少次就用while。
8.4.2 while循环语法
while [condition] #条件为真开始循环,条件为假退出循环
do
commands
done
8.5 until
until语法
until [condition] #条件为假才会循环,条件为真until停止循环
do
commands
done
8.6 case多条件分支语句
一、case介绍
特点:根据给予的不同条件执行不同的代码块
二、case语法
case 变量 in
条件1)
执行代码块1
;;
条件2)
执行代码块2
;;
esac
注意:每个代码块执行完毕要以;;结尾代表结束,case结尾要以esac结束
8.3 shell特殊变量
特殊参数
1. $* 代表所有参数,其间隔为IFS内定参数的第一个字元
2. $@ 与*星号类同,不同之处在于不参照IFS
3. $# 代表参数数量
4. $ 执行上一个指令的返回值
5. $- 最近执行的foreground pipeline 的选项参数
6. $$ 本身的process ID
7. $ 执行上一个背景指令的PID
8. $_ 显示出最后一个执行的命令
9. $N shell的第几个外传参数
九、shell函数
9.1 函数介绍
代码模块化
9.2 函数语法
语法一
函数名() {
代码块
return N
}
语法二
function 函数名{
代码块
return N
}
9.3 函数应用
定义好函数后,如果想调用该函数,只需要通过函数名调用即可
十、正则表达式
10.1 正则表达式介绍
正则表达式是一种文本匹配模式,可以用来检查一个字符串是否含有某种子串、将匹配的子串替换或者从某个字符串中取出某个条件的子串。
shell中,并不是所有命令都支持正则表达式,常见的命令有 grep,sed,awk等
10.2 特殊字符
定位使用技巧:同时锚定开头和结尾,做精确匹配;单一锚定开头和结尾,做模糊匹配。
定位符 说明
^ 锚定开头, ^a 以a开头 默认锚定一个字符
$ 锚定结尾,a$ 以a结尾 默认锚定一个字符
匹配符 说明
. 匹配除回车以外的任意字符
() 字符串分组
[] 定义字符类,匹配括号中的一个字符
[^] 表示否定括号中出现字符类中的字符,取反
\ 转义字符
| 或
限定符 说明
* 某个字符之后加星号表示该字符不出现或者出现多次
? 与星号相似,但略有变化,表示该字符出现一次或者不出现
+ 与星号相似,表示前面字符出现一次或多次,但是必须出现一次
{n,m} 某个字符之后出现,表示该字符最少出现n次,最多出现m次
{m} 正好出现m次
POSIX字符
特殊字符 说明
[:alnum:] 匹配任意字符0-9 a-z A-Z
[:alpha:] 匹配任意字母,大写或者小写
[:digit:] 数字0-9
[:graph:] 非空字符(非空控制字符)
[:lower:] 匹配所有小写 [a-z]
[:print:] 匹配所有可见字符 包括空格和TAB
[:punct:] 匹配特殊输入符号+-=)(*&^%$#@!~`|\"'{}[]:;?/>.<;注意它不包含空格和TAB,这个集合不等于^[a-zA-Z0-9]
[:space:] 匹配空格字符
[:upper:] 匹配所有大写 [A-Z]
[:xdigit:] 16进制数 [0-f]
[:blank:] 匹配范围为 空格和TAB键
[:cntrl:] 匹配控制键 例如 ^M 要按 ctrl+v 再按回车 才能输出
注意 [[]] 双中括号的意思:第一个中括号是匹配符 匹配中括号中的任意一个字符 ,第二个[]是格式,如[:digit:]
[root@www ~]# egrep "^a[[:alpha:]]c$" file
十一、shell对文件的操作
11.1 shell 对文件操作介绍
在shell脚本中操作文件而不用vim nano等工具
11.2 sed命令
11.2.1
sed命令编辑对象是文件中的行,可以理解为:
文本中的一行--> sed处理数据(缓存)-->电脑屏幕
11.2.2 sed命令
语法:
sed [options] '{command}[flags]' [filename]
sed的常用选项:
-r:使用扩展正则表达式
-e:它告诉sed将下一个参数解释为一个sed指令,只有当命令行上给出多个sed指令时才需要使用-e选项
-f:后跟保存了sed指令的文件
-i:直接对内容进行修改,不加-i时默认只是预览,不会对文件做实际修改
-n:取消默认输出,sed默认会输出所有文本内容,使用-n参数后只显示处理过的行
-i.bak:修改时同时创建.bak备份文件
! :取反
sed的常用命令
a:追加 向匹配行后面插入内容
c:更改 更改匹配行的内容
i:插入 向匹配行前插入内容
d:删除 删除匹配的内容
s:替换 替换掉匹配的内容
p:打印 打印出匹配的内容,通常与-n选项和用
=:用来打印被匹配的行的行号
n:读取下一行,遇到n时会自动跳入下一行
r,w:读和写编辑命令,r用于将内容读入文件,w用于将匹配内容写入到文件
参考https://blog.csdn.net/wdz306ling/article/details/80087889/
11.3 sed小技巧
$= 统计文本有多少行
sed -n '$=' data2
5
十二、shell对输出流的处理
一个集过滤、提取、运算为一体的命令awk
12.1 awk介绍
awk认为文件中的每一行是一条记录,记录与记录的分隔符为换行符,每一列是一个字段,字段与字段之间的分隔符默认是一个或者多个空格或者tab制表符
awk的工作方式是读取数据,将每一行数据视为一条记录(record),每条记录以字段分隔符分成若干段,然后输出各个字段的值。
awk语法
awk [options][BEGIN]{program}[END] file
常用命令选项
-F fs 指定描绘一行中数据字段的文件分隔符 默认为空格
-f file 指定读取程序的文件名(程序写在file中,用-f调用)
-v var=value 定义awk程序中使用的变量和默认值
awk程序运行的优先级是:
1)BEGIN 在开始处理数据流之前执行,可选项
2)program 如何处理数据流 必选项
3)END 处理完数据流后执行,可选项
12.2 awk的基本用法 -- awk数据提取功能
12.2.1) awk对字段(列)的提取
字段提取:提取一个文本中的一列数据并打印输出
字段相关内置变量
$0 表示整行文本
$1 表示文本行中的第一个数据字段
$N 表示文本行中的第N个数据字段
$NF 表示文本行中最后一个数据字段
#读入test文件的每行数据并把每行数据打印出来
[root@www ~]# awk '{print $0}' test
1 the quick ..
2 the quick ..