一.编程基本概念
编程逻辑处理方式: 顺序执行 循环执行 选择执行
shell编程:过程式、解释执行
编程语言的基本结构: 各种系统命令的组合
数据存储:变量、数组 表达式: a + b 语句:if
程序:指令+数据
程序编程风格:
过程式:以指令为中心,数据服务于指令
对象式:以数据为中心,指令服务于数据
shell程序:提供了编程能力,解释执行
shell脚本: 包含一些命令或声明,并符合一定格式的文本文件
格式要求:首行shebang机制 #!/bin/bash #!/usr/bin/python #!/usr/bin/perl
shell脚本的用途有:
自动化常用命令 执行系统管理和故障排除 创建简单的应用程序 处理文本或文件
二.创建shell脚本
第一步:使用文本编辑器来创建文本文件 第一行必须包括shell声明序列:#! #!/bin/bash 添加注释 注释以#开头
第二步:运行脚本 给予执行权限,在命令行上指定脚本的绝对或相对路径 直接运行解释器,将脚本作为解释器程序的参数运行——chmod +x a.sh:加上执行权限
如上图所示,在脚本中已经加入了cd切换命令,并显示当前目录,但是在下图中,不同的执行命令,显示的结果却不相同——"通过相对路径和bash的执行方式的效果,只在脚本内部有效,并不影响外部 但是source执行方式,既对脚本内部生效,也对脚本外部有效"
例子:在脚本外部定义,变量名字为mage,在脚本内部定义变量名为wang 结果显示内部脚本命令并不影响外部定义的变量
(3)脚本规范
脚本代码开头约定
1、第一行一般为调用使用的语言
2、程序名,避免更改文件名为无法找到正确的文件
3、版本号
4、更改后的时间
5、作者相关信息
6、该程序的作用,及注意事项
7、最后是各版本的更新简要说明
(4)简单的基础脚本的编写——显示"hello my friends"
(5)脚本调试
检测脚本中的语法错误 bash -n /path/to/some_script
调试执行 bash -x /path/to/some_script
(6)变量
变量:命名的内存空间
数据存储方式: 字符: 数值:整型,浮点型
变量:变量类型
作用: 1、数据存储格式 2、参与的运算 3、表示的数据范围
类型: 字符 数值:整型、浮点型
强类型:变量不经过强制转换,它永远是这个数据类型,不 允许隐式的类型转换。一般定义变量时必须指定类型、参与 运算必须符合类型要求;调用未声明变量会产生错误 ——如 java,c#
弱类型:语言的运行时会隐式做数据类型转换。无须指定类 型,默认均为字符型;参与运算会自动进行隐式类型转换; 变量无须事先定义可直接调用
如:bash
不支持浮点数,php
变量命名法则:
1、不能使程序中的保留字:例如if, for
2、只能使用数字、字母及下划线,且不能以数字开头
3、见名知义
4、统一命名规则:驼峰命名法
大驼峰:每个单词首字母都是大写
小驼峰的命名方法:第一个单词的首字母是小写,后面单词首字母都是大写
(7)bash中变量的种类
根据变量的生效范围等标准:
- 本地变量
生效范围为当前shell进程;对当前shell之外 的其它shell进程,包括当前shell的子shell进程均无效
变量赋值:name='value'——name=mage
可以使用引用value:
(1) 可以是直接字串; name="root"
(2) 变量引用:name="$USER"
(3) 命令引用:name=COMMAND
name=$(COMMAND) ——name=hostname
变量引用:${name}
$name "":弱引用,其中的变量引用会被替换为变量值
'':强引用,其中的变量引用不会被替换为变量值,而保 持原字符串
显示已定义的所有变量:set
删除变量:unset name
在一个终端窗口定义变量
但是在另一个终端窗口不显示变量名
通过pstree -p来查看进程编号,可以看出进程号并不一样,生效范围只是本地变量有效
- 环境变量:生效范围为当前shell进程及其子进程
变量声明、赋值: export name=VALUE declare -x name=VALUE
变量引用:$name, ${name}
显示所有环境变量: env printenv export declare -x
删除变量: unset name
在b.sh文件中定义
最后子进程可以实现对父进程内容的调用
但是父进程不能去继承子进程新定义的变量的内容
- 位置变量:$1, $2, ...来表示,用于让脚本在脚本代码 中调用通过命令行传递给它的参数
位置变量:在脚本代码中调用通过命令行传递给脚本的参数
$1, $2, ...:对应第1、第2等参数——vim f11.sh
shift [n]——换位置
$0: 命令本身——vim f11.sh
$: 传递给脚本的所有参数,全部参数合为一个字符串
$@: 传递给脚本的所有参数,每个参数为独立字符串
$#: 传递给脚本的参数的个数
$@ $ 只在被双引号包起来的时候才会有差异
set -- 清空所有位置变量- 特殊变量:$?, $0, $*, $@, $#,$$
只读和位置变量
0 代表成功
只读变量:只能声明,但不能修改和删除
声明只读变量:
readonly name declare -r name
查看只读变量:
readonly –p
(8)退出状态
进程使用退出状态来报告成功或失败
1-255代表失败 $? 变量保存最近的命令退出状态 bash自定义退出状态码
exit [n]:自定义退出状态码 )
注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出 状态取决于exit命令后面的数字
注意:如果未给脚本指定退出状态码,整个脚本的退出状态码 取决于脚本中执行的最后一条命令的状态码
在编辑脚本的时候,给exit添加一个小括号,代表的意思是给自己开了一个子进程,所以不会影响接下来的命令
三.算术运算
bash中的算术运算:help let
+, -, *, /, %取模(取余), **(乘方)
实现算术运算:
- (1) let var=算术表达式
[root@centos7 ~]#a=20 [root@centos7 ~]#b=30 [root@centos7 ~]#c=$a+$b [root@centos7 ~]#let c=$a+$b [root@centos7 ~]#echo $c 50
(2) var=$[算术表达式]——var=$[a+b] echo $var
(3) var=$((算术表达式)) ——echo $((a+b))
(4) var=$(expr arg1 arg2 arg3 ...)——支持数字运算
(5) declare –i var = 数值
(6) echo ‘算术表达式’ | bc ——计算从1加到100
乘法符号有些场景中需要转义,如*
bash有内建的随机数生成器:$RANDOM(0-32767)
echo $[$RANDOM%50] :0-49之间随机数赋值
增强型赋值: +=, -=, *=, /=, %=
let var++ ——
let varOPERvalue
例如:let count+=3 自加3后自赋值 ——let a+= 5 相当于a=a+5
自增,自减:
let var+=1
let var-=1
let var-
逻辑运算
true, false 1, 0
例子:当a=5,b=8时,通过异或实现a与b的互换
与: 全是1结果为1,有0则是0
1 与 1 = 1 1 与 0 = 0 0 与 1 = 0 0 与 0 = 0
或:有1则为1,全0则是0
1 或 1 = 1
1 或 0 = 1
0 或 1 = 1
0 或 0 = 0
非:!就是取反
! 1 = 0
! 0 = 1
短路运算
短路与 第一个为0,结果必定为0 ——cmd1 &&cmd2:cmd1为假的时候,不去执行后面的命令,结果也为假
第一个为1,第二个必须要参与运算 ——cmd1 && cmd2:cmd1为真的时候,去执行cmd2,cmd2为真的时候,结果为真,cmd为假的时候,结果为假
短路或 第一个为1,结果必定为1——cmd1 || cmd2:cmd1为真的时候,不去执行cmd2,结果为真
cmd2第一个为0,第二个必须要参与运算 ——cmd1为假的时候,cmd2为真的时候,去执行cmd2 ,结果为真,cmd2为假的时候,结果为假
异或:^ 异或的两个值,相同为假,不同为真
条件测试
(1) 判断某需求是否满足,需要由测试机制来实现 专用的测试表达式需要由测试命令辅助完成测试过程
(2) 测试命令: test EXPRESSION
例1:如果比较两个值相等,则输出结果显示为'equal',可以采用短路与来实现 a=xcv,b=xcv
例2:此时,改变b的值,让其不等于a,那么采用短路或实现输出结果为'not equal'
[ EXPRESSION ] =等价test变量
在test测试用法中空字符等同于没有赋值,而给变量赋值0或是空格,就是赋值输出结果为真
test:
-n:非空为真判断变量是否为空一定要加双引号
-z:空为真当给sdc赋值后,不再为空,那么空为假,则不执行下面的命令
数值测试:
-gt 是否大于
例1:
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于
例2:
例3:读取磁盘分区利用率,如果利用率大于10则报警
字符串测试:
"在没有赋值的时候,给字符串加上引号"
== 是否等于 > ascii码是否大于ascii码
< 是否小于 != 是否不等于
=~ 左侧字符串是否能够被右侧的PATTERN所匹配 注意: 此表达式一般用于[[ ]]中扩展的正则表达式
[[ EXPRESSION ]] ——支持正则表达式
注意:EXPRESSION前后必须有空白字符,在正则表达式中,字符串不用加引号
四.Bash的文件测试
(1)存在性测试
-a FILE:同-e
-e FILE: 文件存在性测试,存在为真,否则为假
存在性及类别测试
-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件
-h FILE 或 -L FILE:存在且为符号链接文件 ——判断文件类型的时候先判断该文件是否为软连接
-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件
(2)Bash的文件权限测试
文件权限测试:
-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行
文件特殊权限测试:
-u FILE:是否存在且拥有suid权限
-g FILE:是否存在且拥有sgid权限
-s FILE: 是否存在且非空
-k FILE:是否存在且拥有sticky权限
(3)Bash的文件属性测试
文件大小测试:
文件是否打开:
-t fd: fd表示文件描述符是否已经打开且与某终端相关
-N FILE:文件自动上一次被读取之后是否被修改过
-O FILE:当前有效用户是否为文件属主
-G FILE:当前有效用户是否为文件属组
(4)使用read命令来接受输入
使用read来把输入值分配给一个或多个shell变量
-p 指定要显示的提示 ——read -p
-s 静默输入,一般用于密码
-n N 指定输入的字符长度N
-d ‘字符’ 输入结束符
-t N TIMEOUT为N秒 read 从标准输入中读取值,给每个单词分配一个变量
所有剩余单词都被分配给最后一个变量
read -p “Enter a filename: “ FILE