一、简介
1、概念
shell就是一个计算机应用程序,跟QQ、微信等类似,但是他主要是提供计算机的操作界面,例如我们所使用Windows操作系统的图形操作界面和cmd.exe命令行操作界面。shell并不是操作系统内核,可以看成是内核外边的壳,可以实现人机友好交互。
shell同时也可以看成是一种命令语言,本身是用C语言编写的,用shell命令可以编写程序,即我们所说的脚本程序(shell script),所以shell与shell script并不是同一个概念,但通常说shell脚本时就直接说成shell了。在本节所说的shell编程其实就是用shell命令语言编写的shell script。
2、分类
主要分为图形界面shell和命令行式shell两类
图形界面:Graphical User Interface shell 即 GUI shell,应用最常见,例如个人windows系统大部分都是GUI shell
命令行式:Command Line Interface shell ,即CLI shell,个人应用较少,主要是在服务器领域,例如服务器领域的linux操作系统大部分都是CLI shell
3、发展历史
二、编程风格
1、编程范式
面向对象:以数据为中心,考虑先如何组织数据,指令服务于数据。
面向过程:以指令为中心,来进行写程序,数据服务于指令。
2、编程语言
低级:汇编语言
高级:需要进行编译解释的语言
编译:高级语言-->编译器-->目标代码
解释:高级语言-->解释器-->机器代码
可以看出shell脚本语言是高级语言,需要解释器解释后才能执行
程序执行方式:程序最终都是要转成机器代码才能在计算机上执行,机器代码就是二进制指令
3、执行模式
顺序执行
循环执行 for while until
选择执行 if elsif case
三、编程结构
1、程序形式
整个程序最终就以文本文件的形式存在,就是所说的一个脚本文件。
2、程序组成
一般在脚本顶行添加解释器路径 #!/bin/bash
变量、数组等基本元素
构成一个表达式
多个表达式构成一个语句
多个语句构成整个脚本文件
结构的核心就是调用指令(堆命令,严重依赖当前环境)
四、应用场景
重复 批量事务处理 自动化运维 定期任务执行 (crontab) 服务器运行监控
五、程序执行
1、python程序的执行
shell脚本的执行类似于python脚本的执行,我们先来看python文件的执行过程,python脚本的执行分为两类,每一类都有绝对路径与相对路径两种执行方式。
1、交互式shell环境下直接执行
2、使用解释器执行
2、shell程序执行
1、在交互式shell环境直接执行
2、使用解释器执行
3、前面加点执行
4、使用source执行
5、bash的单步执行
六、shell变量
1、概念
变量:是一段内存空间的引用
赋值:变量名=值
注意>>变量在赋值是不能再前面带$
2、命名规则
变量名只能包含字母、数字和下划线,并且不能以数字开头
变量名区分大小写
尽量能见名知义
变量不能以数字开头
3、变量分类
局部变量:变量仅对当前Shell进程有效
定义变量:Var_Name="Value"
环境变量:对当前shell进程及其子shell进程有效(但不可跨终端)
定义变量:export Var_Name=”Value”
或 Var_Name="Value" export Var_Name
环境变量对于当前shell和子shell都有效
查看系统内置环境变量 env
4、引用变量
${Var_Name}:引用变量
通常情况下大括号可以省略,可以简写成:$Var_Name
echo $Var_Name :打印变量的值
5、撤销变量 unset Var_Name
6、变量替换
通常情况下大括号可以省略 如果变量名后面要跟如下内容:字符串(包括大小字符串)、数字或下划线,那么变量名就一定要用大括号包起来
7、命令替换
1、$(命令1;命令2......) (有些shell不兼容,tsh)
2、倒引号 ``,`命令1;命令2......` (兼容性好,但是可读性差)
括号或倒引号内命令的执行结果(标准输出)返回给当前shell,相当于产生了一个新的命令,其标准输出可被echo或者被当前shell的命令所使用
8、变量在单双引号中的引用
‘’ 单引号: 强引用,变量替换不会进行,变量名不会被替换成变量对应的值
"" 双引号:弱引用,能够执行变量替换,变量名可以被替换成变量对应的值
9、位置变量
变量形式:$1, $2, $3, ......, $n ($9以后需要用${10})
作用:用来接收给shell脚本所传递的参数,第一个参数用$1来获取,第二个参数用$2来获取,......
例1:随机在系统内找两个文本文件,分别输出它们空行的数量
10、特殊变量
$0 : 脚本名称自身
$? : 上一条命令的执行状态
状态用数字表示:0-255
0:表示成功
1-255:失败,1.2.127.255预留
$# : 记录位置参数个数的总和
$* : 详细列出所有的位置参数
$$ : 当前所在进程的进程号
七、算术运算
1、declare
2、expr
3、let
4、$[算数表达式]
5、$((算术表达式))
7、算数运算符
单个运算符:+,- ,*,/,%(余数)
组合运算符:+= ,-=,*=,/=,%=
a+=b -----> a=a+b
a-=b ------> a=a-b
a*=b --------> a=a*b
a /=b ---------> a=a/b
变量++:a++ ----> a=a+1
变量--:a-- ------> a=a-1
注意:除法只能使用整数部分
例2:随机选择两个文本,计算出两个文本生效的行数
八、交互式输入、输出
输入:read [-p "提示信息"] 变量名
输出:echo $变量名
九、条件判断
1、比较运算符
文件操作符
-d:测试是否为目录(Directory)
-e:测试目录或文件是否存在(Exist)
-f:测试是否为文件(File)
-r:测试当前用户是否有权限读取(Read)
-w:测试当前用户是否有权限写入(Write)
-x:测试当前用户是否可执行(Excute)该文件
-L:测试是否为符号连接(Link)文件
可以使用echo $?来判断,0为真,非0为假
数字操作符
-eq -gt -ge -lt -le -ne
等于 大于 大于等于 小于 小于等于 不等于
-eq = equals to =
-gt = great than >
-ge = great or equals to >=
-lt = less than <
-le = less or equals to <=
-ne = not equals to !=,<>
字符串操作符
= :字符串内容相同
!= :字符串内容不同,! 号表示相反的意思
-z :字符串内容为空
2、逻辑运算符
与: &&
或:||
非:!
0:真
1:假
&& | 1 | 0 |
1 | 1 | 1 |
0 | 1 | 0 |
|| | ||
1 | 1 | 0 |
0 | 0 | 0 |
! | 0 | 1 |
3、判断方法
test 条件表达式
[ 操作符 文件或目录 ]或者[[ 操作符 文件或目录 ]](中括号与表达式之间一定要有空格)
十、循环结构
1、for循环
格式:
for var_Name in 列表; do
循环体(正常执行的执行命令)
语句1......
done
seq命令:类似于python里的range函数
例3:生成5个空文件,文件名从1到10,后缀”.txt”
例4:添加user1到5用户,每添加一个显示/etc/passwd的最后一行信息
例5:再把例4创建的5个新用户和例3创建的5个空文件删除
例6:求从1加到100的结果
2、while循环
格式:
while [条件]; do
循环体(正常执行的执行命令)
语句1......
done
退出循环:
break:结束并退出循环
continue:在循环中不执行continue下面的代码,转而进入下一轮循环
退出脚本:
exit:常带一个整数给系统,如 exit 0
例7:计算所有参数的和
3、until循环
条件测试不成功即进入循环体
格式:
until [条件]; do
循环体(正常执行的执行命令)
语句1......
done
例8:求1到100所有整数的和
十一、选择结构
1、if条件判断
单分支:
if condition; then
statement1
......
fi
例9:变量Name是zhangsan,打印欢迎你
双分支 :
if condition; then
statement1
else
statement2
fi
例10:变量Name是zhangsan,打印欢迎你,否则打印不欢迎
多分支:
if condition; then
statement1
elif condition; then
statement2
...
else
statementn
fi
例11:变量score小于60,打印不及格;60到80之间,打印及格;80到100之间,打印优秀;否则打印分数有误
例12:创建用户,如果创建成功,打印成功;如果失败,打印已存在
例13:for循环打印9*9乘法表
2、case语句
格式 :
case 变量引用 in
正则表达式1)
分支1
;;
正则表达式2)
分支2
;;
正则表达式n)
分支n
;;
*)
默认分支
;;
esac
例14:变量score 在1和9之间太低了,score小于60,打印不及格;60到80之间,打印及格;80到100之间,打印优秀;否则打印分数有误
十二、函数
格式:
function 函数名() {
命令序列
......
return xxx
}
调用:函数名 [ 参数1 ] [ 参数2 ] .....
例15:打印参数