1.1 程序组成
- 程序:算法+数据结构
- 数据:是程序的核心
- 数据结构:数据在计算机中的类型和组织方式
- 算法:处理数据的方式
1.2 程序编程风格
面向过程语言:
- 有顺序,做一件事情,第一步干什么,第二步干什么
- 问题规模小,可以步骤化,按部就班处理
- 以指令为中心,数据服务于指令
- C,shell
面向对象语言:
- 对象是类的具象,是一个实体
- 问题规模大,复杂系统
- 以数据为中心,指令服务于数据
- java, C#, python, golong等
1.3 编程语言
计算机运行二进制指令
编程语言分为低级语言和高级语言
1.4 编程逻辑处理方式
顺序结构:程序按照从上到小顺序执行
选择结构:程序执行过程中,根据条件的不同,进行选择不同的分支继续执行
循环结构:程序执行过程中需要重复执行多次某段语句
2 shell脚本语言的基本用法
2.1 shell脚本的用途
将简单的命令组合完成复杂的工作,提高工作效率,减少手工命令的重复输入,一定程度上避免人为错误。用于实现日常性的,重复性的运维工作。
2.2 shell脚本基本结构
shell 脚本编程:基于过程式、解释执行的语言
编程语言的基本结构:
- 各种系统命令的组合
- 数据存储:变量、数组
- 表达式:a+b
- 控制语句:if
shell脚本:包含一些命令或声明,并符合一定格式的文本文件
格式要求:首行shebang机制
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/per1
2.3 shell脚本创建过程
第一步:使用文本编辑器来创建文本文件
第一行必须包括shell声明序列:#!
添加注释,注释以#开头
第二步:加执行权限
给予执行权限,在命令行上指定脚本的绝对或相对路径
第三步:运行脚本
直接运行解释器,将脚本作为解释器程序的参数运行
2.4 shell脚本注释规范
- 第一行一般为调用使用的语言
- 程序名,避免更改文件名为无法找到正确的文件
- 版本号
- 更改后的时间
- 作者相关信息
- 该程序的作用,及注意事项
- 最后是各版本的更新简要说明
2.6 shell脚本调试
只检测脚本中的语法错误,但无法查出命令错误,但不真正执行脚本
bash -n /path/to/some_script
调试并执行
bash -x /path/to/some_script
脚本错误常见的有三种:
- 语法错误:导致后续的命令不执行,可以用bash -n检查错误,提示的出错行数不一定是准确的
- 命令错误:默认后续的命令还会继续执行,用bash -n无法检查出来,可以用bash -x进行观察
- 逻辑错误:只能使用bash -x进行观察
2.7 变量
变量表示命名的内存空间,将数据放在内存空间中,通过变量名引用,获取数据。
2.7.1 变量
变量类型:
- 内置变量
- 用户自定义变量
不同的变量存放的数据不同,决定了数据的存储方式,参与的运算,表示的数据范围
变量数据类型:
- 字符
- 数值:整型、浮点型,bash不支持浮点数
2.7.3 编程语言分类
- 静态和动态语言
- 强类型和弱类型语言
2.7.4 shell中变量命名法则
- 不能使程序中的保留字和内置变量
- 只能使用数字、字母及下划线,且不能以数字开头,不支持短横线,和主机名相反。
- 用英文单词命名,不用简写
- 变量名大写
- 局部变量小写
- 函数名小写
变量赋值:
name=' '
变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存,脚本中的变量会随着脚本结束,也会自动删除
弱引用和强引用
“$name” 弱引用,其中的变量引用会被替换为变量值
‘$name’ 强引用,其中的变量引用不会被替换为变量值,而保持原字符串
删除变量:
unset <name>
2.7.6 环境变量
- 可以使子进程继承父进程的变量,但是无法让父进程使用子进程的变量
- 一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程
- 一般只在系统配置文件中使用,在脚本中较少使用
2.7.7 只读变量
只能声明定义,但后续不能修改和删除,即常量
声明只读变量:
readonly name
declare -r name
查看只读变量:
readonly [-p]
declare -r
2.8 格式化输出printf
格式:
printf "指定的格式" “文本1” “文本2”
常用格式替换符
替换符 | 功能 |
---|---|
%s | 字符串 |
%f | 浮点格式 |
%o | 八进制整数 |
%b | 相对应的参数中包含转义字符时,可以使用此替换符进行替换,对应的转义字符会被转义 |
%c | ASCII字符,即显示对应参数的第一个字符 |
%d,%i | 十进制整数 |
%u | 不带正负号的十进制值 |
%x | 十六进制值(a-f) |
%X | 十六进制值(A-F) |
%% | 表示%本身 |
常用转义字符
转义符 | 功能 |
---|---|
\a | 警告字符,通常为ASCII的BEL字符 |
\b | 后退 |
\f | 换页 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
|表示\本身 |
2.9 算术运算
shell 允许在某些情况下对算术表达式进行求值。
bash只支持整数,不支持小数。
2.10 逻辑运算
1,真
0,假
&,与
和0相与,结果为0
和1相与,结果保留原值
|,或
和1相或结果为1,和0相或,结果保留原值
!,非
^,异或
异或的两个值,相同为假,不同为真。两个数字1,2异或得到结果为3,3再和任意两者之一1异或,将得到另一个值2
短路运算
短路与
a 短路与 b
第一个a结果为真(1),第二个b必须要参与运算,才能得到最终结果
第一个a结果为假(0),总的结果必定为0,因此不需要执行b
短路或
a 短路或 b
第一个a结果为真(1),总的结果必定为1,因此不需要执行b
第一个a结果为假(0),第二个b必须要参与运算,才能得到最终的结果。
2.11 条件测试命令
条件测试:判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成测试过程,实现评估布尔声明,以便用在条件性环境下进行执行。
若真,则状态码变量$? 返回0
若假,则状态码变量 $? 返回1
条件测试命令
- test EXPRESSION
- [ EXPRESSION ]
- [[ EXPRESSION ]]
注意:EXPRESSION前后必须有空白字符
2.11.1 变量测试
- v NAME
#判断NAME变量是否定义
-R NAME
#判断NAME变量是否定义并且是名称引用
2.11.2 数值测试
-eq
是否等于
-ne
是否不等于
-gt
是否大于
-ge
是否大于等于
-lt
是否小于
-le
是否小于等于
2.11.3 字符串测试
test 和 [ ]用法
-z string 字符串是否为空,没定义或空为真,不空为假
-n string 字符串是否不空,不空为真,空为假
[[ ]]用法
当使用正则表达式或通配符使用[[ ]],其他情况一般使用[ ]
2.11.4 文件测试
- -a/-e file:文件存在性测试,存在为真,否则为假
- -b file:是否存在且为块设备文件
- -c file:是否存在且为字符设备文件
- -d file: 是否存在且为目录文件
- -f file: 是否存在且为普通文件
- -h/-L file:存在且为符号链接文件
- -p file:是否存在且为命名管道文件
- -s file:是否存在且为套接字文件
2.12 关于()和{ }
(CMD1;CMD2;…)和{CMD1;CMD2;…}都可以将多个命令组合在一起,批量执行。
(list)会启动shell,并且list中变量赋值及内部命令执行后,将不在影响后续的环境。
{list} 不会启动shell,在当前shell中运行,会影响当前shell环境
2.13 使用read 命令来接受输入
使用read来把输入值分配给一个或多个shell变量,read从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量,如果变量名没有指定,默认标准输入的值赋值给系统内置变量reply.
格式:
read [option] [name...]
选项:
-p 指定要显示的提示
-s 静默输入,一般用于密码
-n N 指定输入的字符长度N
-d ‘字符’ 输入结果符
-t N timeout为n秒
3 bash shell 的配置文件
3.1 按生效范围划分两类
全局配置:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
个人配置:
~/.bash_profile
~/.bashrc
3.2 shell登录两种方式分类
3.2.1 交互式登录
- 直接通过终端输入账号密码登录
- 使用su -UserName切换的用户
3.2.2 非交互式登录
- su UserName
- 图形界面下打开的终端
- 执行脚本
- 任何其他的bash实例
3.3 按功能划分分类
3.3.1 Profile类
profile类为交互式登录的shell提供配置
全局:/etc/profile,/etc/profile.d/*.sh
个人:~/.bash_profile
功用:
(1)用于定义环境变量
(2)运行命令或脚本
3.3.2 Bashrc类
bashrc类:为非交互式和交互式登录的shell提供配置
全局:/etc/bashrc
个人:~/.bashrc
功用:
(1)定义命令别名和函数
(2)定义本地变量
3.4 编辑配置文件生效
修改profile和bashrc文件后需生效两种方法:
1.重新启动shell进程
2.source|. 配置文件
3.5 Bash退出任务
保存在~/.bash_logout文件中(用户),在退出登录shell时运行
功能:
创建自动备份
清除临时文件
4 函数function
4.1 函数介绍
函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程,它与shell程序上是相似的,不同的是它不是一个单独的进程,不能独立进行,而是shell程序的一部分。
函数和shell程序区别
- shell程序在子shell中运行
- 函数在当前shell中运行,因此在当前shella中,函数可对shell中变量进行修改。
5.2 管理函数
函数由两部分组成:函数名和函数体
帮助参看:help function
5.3 函数调用
函数的调用方式
- 可在交互式环境下定义函数
- 可将函数放在脚本文件中作为它的一部分
- 可放在只包含函数的单独文件中
调用:函数只有被调用才会执行,通过给定函数名调用函数,函数名出现的地方,会被自动替换为函数代码
函数的生命周期:被调用时创建,返回时终止。
5.4 函数返回值
-
使用echo等命令进行输出
-
函数体中调用命令的输出结果
函数的退出状态码: -
默认取决于函数中执行的最后一条命令的退出状态码
-
自定义退出状态码,其格式为:
return 从函数中返回,用最后状态命令决定返回值
return 0 无错误返回
return 1-255 有错误返回
5.5 环境函数
类似于环境变量,也可以定义环境变量,使子进程也可使用父进程定义的函数
6 其他脚本相关工具
6.1 信号捕捉trap
6.2 创建临时文件mktemp
mktemp命令用于创建并显示临时文件,可避免冲突。
6.3 安装复制文件install
install功能相对于cp, chmod, chown, chgrp等相关工具的集合