shell 脚本编程

shell 脚本编程

1. 编程基础

1.1 程序组成

  • 程序:算法+数据结构
  • 数据:程序的核心
  • 数据结构:数据在计算机中的类型和组织方式
  • 算法:处理数据的方式

1.2 程序编程风格

  • 面向过程语言
    1.做一件事情,排出步骤,第一步干什么,第二部干什么。如果出现情况A,做什么处理,如果出现B情况,做什么处理
    2. 问题规模小,可以步骤化,按部就班处理
    3. 以指令为中心,数据服务于指令
    4. C, shell
  • 面向对象语言
    1. 一种认识世界,分析世界的方法论。将万事万物抽象为各种对象
    2. 类是抽象的概念,是万事万物的抽象,是一类事物的共同特征的集合
    3. 对象是类的具象,是一个实体
    4. 问题规模大,复制系统
    5. 以数据为中心,指令服务于数据
    6. java ,C# ,python ,golangdeng

1.3 编程语言

计算机:运行二进制指令
编程语言:人与计算机之间的交互的语言。分为:低级语言和高级语言

  • 低级编程语言:
    1.机器:二进制的0和1的序列,称为机器指令。与自然语言差异太大
    2. 汇编:用一些助记符代替机器指令,称为汇编语言
  • 高级编程语言
    1. 编译:高级语言–>编译器–>机器代码文件–>执行,如C,C++
    2. 编译:高级语言–>执行–>解释器–>机器代码文件,如:shell,python,JavaScript,perl

1.4 三种处理逻辑

  • 顺序执行:程序从上到下顺序执行
  • 选择执行:程序执行过程中,根据条件的不同,进行选择不同分支继续执行
  • 循环执行:程序执行过程中需要重复执行多次某段语句

2. shell 脚本语言的基本用法

2.1 shell 脚本的用途

  • 将简单的命令组合完成复杂的工作,自动化执行命令,提高工作效率
  • 减少手工命令的重复输入,一定程度上避免人为错误
  • 将软件或应用的安装及配置实现标准化
  • 用于实现日常性的,复杂性的运维工作,如:文件的打包压缩备份,监控系统运行状态并实现警告等

2.2 shell 脚本基本结构

shell 脚本编程:基于过程式、解释执行的语言
编程语言的基本结构

  • 各种系统命令的组合
  • 数据存储:变量、数组
  • 表达式:a+b
  • 控制语句:if

2.3 shell 脚本调试

  • bash -n 检测脚本的语法错误,但无法检测命令错误,不真正执行脚本
  • bash -x 调试并执行

总结:脚本错误常见有三种

  • 语法错误,会导致后续的命令不执行,可以用bash -n 检查错误,提示的出错行数不一定是准确的
  • 命令错误,默认后续的命令还会继续执行,bash -n 无法检测,可以使用bash -x进行观察
  • 逻辑错误:只能bash -x 进行观察

2.4 变量

2.4.1 变量

变量表明命名的内存空间,将数据保存在内存空间中,通过变量名引用,获取数据

2.4.2 变量类型

变量类型:

  • 内置变量,如:PS1,PATH,UID,HOSTNAME,等
  • 用户自定义变量
    不同的变量存放的数据不同,决定了以下
  • 数据存储方式
  • 参与的运算
  • 表示的数据范围
    变量的数据类型:
  • 字符
  • 数值:整型,浮点型,bash不支持浮点数
2.4.3 编程语言分类

静态和动态语言

  • 静态编译语言:使用变量前,先声明变量类型,之后又类型不能改变,如:java,C
  • 动态编译语言:不用事先声明,可随时改变类型,如:bash,Python
    强类型和弱类型语言
  • 强类型语言:不同类型数据操作,必须经过强制转换成同一类型才能运算,如java,python
  • 弱类型语言:语言的运行会隐式做数据转换。无须指定类型,默认均为字符,参与运算会自动进行转换,变量无须事先定义可直接调用。如bash,php,javascript
2.4.4 shell中变量命名法则
  • 不能使用程序中的保留字和内置变量:if,for
  • 只能使用数字,字母及下划线,且不能数字开头,注意:不支持短横线-,与主机名相反
  • 见名知意,用英文单词命名,并体现出实际作用,不要用简写
  • 同一命名规则,驼峰命名法studentname,大驼峰StudentName,小驼峰studentName
  • 变量名大写
  • 局部变量小写
  • 函数名小写
2.4.5 变量定义和引用

变量的生效范围

  • 普通变量:生效范围为当前shell;对除当前shell之外的其他shell,包括子shell均无效
  • 环境变量:当前shell及子进程
  • 本地变量:当前shell中某代码片段,通常指函数

变量赋值

name='value'
直接字串 name='root'
变量引用 name='$USER'
命令引用 name=`COMMAND` 或 name=$(SOMMAND)

变量引用

$naem
${name}

弱引用和强引用

  • “$name” 弱引用,其中的变量引用会被替换为变量值
  • “${name}” 强引用,其中的变量引用不会被替换为变量值,保存原字符串

显示已定义的所有变量

set

删除变量

unset <name>
2.4.6 环境变量

环境变量

  • 可以使子进程继承父进程的变量,但无法让父进程使用子进程的变量
  • 一般子进程修改从父进程继承的变量,将会将新的值传递到孙子进程
  • 一般只在系统配置文件中使用,在脚本中较少使用

变量声明和赋值

#声明赋值
export name=VALUE
declare -x name=VALUE

#或分步进行
name=VALUE
export name

显示所有环境变量

env
printenv
export
declare -x

删除变量

unset name
2.4.7 只读变量

只读变量:只能声明定义,但后续不能修改和删除
声明只读变量

readonly name
declare -r name

查看只读变量

readonly [-p]
declare -r
2.4.8 位置变量

位置变量:在bash shell中内置的变量,在代码中调用通过命令行传递给脚本的参数

$1$2... 对应第1个、第2个等参数,shift [n]换位置
$O   命令本身,包括路径
$*   传递给脚本的所有参数,全部参数合为一个字符串
$@   传递给脚本的所有参数,每个参数为独立字符串
$#   传递给脚本的参数的个数
注意: $@ $*只在被双引号包起来的时候才会有差异

清空所有位置变量

set --

范例:

在这里插入代码片
2.4.9 退出状态码变量

我们浏览网页时,有时会看到404,403等数字,表示网页的错误信息,我们称为状态码。
进行进程时,使用 ? 保 存 状 态 码 的 相 关 数 字 , ?保存状态码的相关数字, ?,?取值范围0-255

  • 0 表示成功
  • 1-255 表示失败

用户可以在脚本中使用exit自定义退出状态码

exit [n]
  • 脚本中一旦遇见exit命令,脚本会立即终止,终止退出状态码取决于exit后的数字
  • 如果脚本未指定退出状态码,脚本的退出状态码取决于最后一个命令的状态码
2.4.10 展开命令行

展开命令执行的顺序

把命令行分成单个命令
展开别名
展开大括号
展开~
命令替换$()和**``**
再次把命令行分成命令
展开文件通配符
重定向
运行命令

防止扩展:

  • 反斜线(\)
  • 单引号(’’)
  • 双引号("")注意变量不能防止扩展

变量扩展

  • `` 反引号,命令替换
  • \ 禁止单个字符扩展
  • !历史命令替换
2.4.11 脚本安全 set
2.4.11.1 $- 变量
  • h:hashell 打开选项,shell会将命令的路径hash下来,避免每次查询,set +h可以关闭
  • i: interactive-comments, 包含这个选项说明当前的shell是一个交互式的shell。所谓的交互式shell,在脚本中,i选项是关闭的
  • m: monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等
  • B: braceexpand, 大括号扩展
  • H: history, H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,如"!"返回上最近的一个历史命令, "!n"返回第n个历史命令
2.4.11.2 set脚本安全
  • u 在扩展一个没有设置的变量时,显示错误信息,等同set -o nounset
  • e 如果一个命令返回一个非0退出状态就退出,等同于 set -o errexit
  • o 显示打开或关闭选项
    显示:set -o
    打开:set -o 选项
    关闭:set +o 选项
  • x 执行命令时,打印命令及参数,类似 bash -x

2.5 格式化输出

printf "指定的格式" "文本1" "文本2

常用格式替换符

替换符功能
%s字符串
%f浮点格式
%b参数中包含转义,可以用此替换,对应的转义字符会被转义
%cASCLL字符,即显示对应参数的第一个字符
%d,%i十进制整数
%o八进制值
%u不带正负号的十进制值
%x十六进制值(a-f)
%X十六进制值(A-F)
%%表示%本身

常用转义字符

转义符功能
\a警告字符
\b后退
\f换页
\n换行
\r回车
\t水平制表符
\v垂直制表符
\\\本身
[root@centos8 ~]#printf "%.2f\n" 1 2 3 4
1.00
2.00
3.00
4.00
[root@centos8 ~]#printf "%-10s %-10s %-4s %s \n" 姓名 性别 年龄 体重 小白 男 15 60 
姓名     性别     年龄 体重 
小白     男        15   60 

2.6 算数计算

shell允许在某些情况下对算术表达式进行求值,比如let和declare,(())和算术扩展,
注意:bash只支持整数,不支持浮点数

% 取模,即取余数
i++ i-- 自增,自减
** 乘方
实现算术运算

  1. let var=算术表达式
  2. ((var=算术表达式))
  3. var=$[算术表达式]
  4. var=$((算术表达式))
  5. var=$(expr arg1 arg2)
  6. declare -r var=数值
  7. echo ‘算术表达式’ |bc
    内建的随机数生成器变量
$RANDOM     取值范围:0-32767

增强型赋值

+= i+=10 相当于 i=i+10
-= i-=j  相当于 i=i-j
/=
%=
++ i++,++i 相当于i=i+1
-- i--,--i 相当于 i=i-1

范例:今有雉兔同笼,上有三十五头,下有九十四足,问雉兔各几何?

read -p "请输入头的数量:"HEAD
read -p "请输入脚的数量:"FOOT                                                                             

RABBIT=$(((FOOT-HEAD-HEAD)/2))
CHOOK=$[HEAD-RABBIT]
echo RABBIT:$RABBIT
echo CHOOK:$CHOOK                    

2.7 逻辑运算

2.7.1 与运算(&)

与运算(&):

1 &1=1
1&0=0
0&1=0
0&0=0

2.7.2 或运算(|)

或运算(|)

1 | 1=1
1 | 0=1
0 | 1=1
0 | 0=0

2.7.3 非(!)

非(!):

!0=1
!1=0

2.7.4 异或(^)

异或(^):
异或的2个值,相同为假,不同为真
2个数字X,Y异或得到的值Z,Z再和任意一个值异或,将得出另一个值

1 ^ 1= 0
1 ^ 0= 1
0 ^ 1= 1
0 ^ 0= 0

2.7.5 短路运算
  • 短路与

CMD1 && CMD2
第一个CMD1结果为真,第二个CMD2必须参与运算,才能得到最终结果
第一个CMD1结果为假,最终结果必为假,第二个CMD2不需要执行

  • 短路与

CMD1 || CMD2
第一个CMD1结果为真,最终结果必为真,第二个CMD2不需要执行
第一个CMD1结果为假,第二个CMD2必须参与运算,才能得到最终结果

2.8 条件测试命令

条件测试:判断某需求是否满足。
若结果为真,则状态码 ? 返 回 0 如 结 果 为 假 , 则 状 态 码 ?返回0 如结果为假,则状态码 ?0?返回非0
条件测试命令

  • test EXPRESSION
  • [EXPRESSION ]
  • [[EXPRESSION]]
    注意:EXPRESSION前后必须有空白字符
2.8.1 变量测试
#判断 NAME 变量是否定义
[ -v NAME ]
#判断 NAME 变量是否定义并且是名称引用
[ -R NAME ]
2.8.2 数值测试

-eq 是否等于 ==
-ne 是否不等于 !=
-gt 是否大于 >
-ge 是否大于等于 >=
-lt 是否小于 <
le 是否小于等于 <=

2.8.3 字符串测试

test和[]用法

-z STRING 是否为空,没定义或空为真,不空为假
-[n] STRING 是否不空,不空为真,空为假
STRING1 = STRING2 是否等于,注意 = 前后有空格
STRING1 != STRING2 是否不等于
> ascii 码是否大于ascii
< 是否小于

[[]] 用法

[[ expression ]]
== 左侧字符串是否和右侧的PATTERN相同
注意:PATTERN为通配符

=~ 左侧字符串是否能把右侧的正则表达式PATTERN匹配
注意:此处为扩展的正常表达式

2.8.4 文件测试
2.8.4.1 存在性测试

-a FIEL 是否存在,存在为真,否则为假
-e FIEL 是否存在,存在为真,否则为假
-b FIEL 是否为块设备文件
-c FIEL 是否为字符设备文件
-d FIEL 是否为目录文件
-f FIEL 是否为普通文件
-h FIEL -L FIEL 是否为符号链接文件
-p FIEL 是否为管道文件
-s FIEL 是否为套接字文件

2.8.4.2 文件权限测试

-r FIEL 是否存在且可读
-w FIEL 是否存在且可xie
-x FIEL 是否存在且可执行
-u FIEL 是否存在且拥于suid权限
-g FIEL 是否存在且拥于sgid权限
-k FIEL 是否存在且拥于sticky权限

注意:最终结果是有用户对文件的实际权限决定,而非文件属性决定

2.8.4.3 文件属性测试

-s FIEL 是否存在且非空
-t fd fd 文件描述符是否在某终端已经打开
-N FIEL 文件自上次读取之后是否被修改过
-O FIEL 当前有效用户是否为文件属主
-G FIEL 当前有效用户是否为文件属组
FIEL1 -ef FIEL2 FIEL1是否是FIEL2的硬链接
FIEL1 -nt FIEL2 FIEL1是否新于FIEL2(mtime)
FIEL1 -ot FIEL2 FIEL1是否旧于FIEL2

2.9 关于()和{}

(){} 都可以讲多个命令组合在一起,批量执行
( list ) 会开启子shell,并且list中的变量赋值及内部命令执行后,请不再影响后续环境
{ list } 不会开启子shell,在当前shell中运行,会影响当前shell环境

2.10 组合测试条件

2.10.1 第一种方式[]

[ EXPRESSION1 -a EXPRESSION2 ] 并且,EXPRESSION1和EXPRESSION2都为真,结果才为真
[ EXPRESSION1 -o EXPRESSION2 ] 或者,EXPRESSION1和EXPRESSION2只要有1个为真,结果就为真
[ ! EXPRESSION ] 取反

注意:-a 和 -o 在[[]]不支持

2.10.2 第二种方式 && ||

COMMAND1 && COMMAND2 并且,短路与,COMMAND1为真,则执行COMMAND2
COMMAND1 || COMMAND2 或者,短路或,COMMAND1为真,则不执行COMMAND2,COMMAND1为假,则执行COMMAND2
! COMMAND 非 取反

2.11 使用read 命令接受输入

使用read来把输入的值,分配到一个或多个变量,read从标准输入中读取值,如果变量没有指定,则默认赋值给内置变量 REPLY

read [options] [name ...]

选项

  • -p 指定要显示的提示
  • -s 静默输入,一般用于密码
  • -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 切换用户

配置文件生效和执行的顺序

# 放在每个文件最前面
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
~/.bash_profile
~/.bashrc
/etc/bashrc

#放在每个文件的最后
/etc/profile.d/*.sh
/etc/bashrc
/etc/profile
/etc/bashrc
~/.bashrc
~/.bash_profile
3.2.3 非交互式登录
  • su username
  • 图形界面下打开终端
  • 执行脚本
  • 任何其他的bash实例

执行顺序

/etc/profile.d/*.sh
/etc/bashrc
~/.bashrc

3.3 按功能

profile和bashrc

3.3.1 Profilelei类

proflie类为交互登录的shell通过配置

  • 全局:/etc/profile ,/etc/profile.d/*.sh
  • 个人:~/.bash_profile
    功用:
  • 用于定义环境变量
  • 运行命令或脚本
3.3.2 Bashrc类

bashrc类:为非交互式和交互式登录的shell通过配置

  • 全局:/etc/bahsrc
  • 个人:~/.bashrc
    功用:
  • 用于定义别名和函数
  • 定义本地变量

3.4 编辑配置文件生效

修改profile和bashrc文件后需生效的2种方法:

  • 重启shell
  • source 或 . 配置文件

3.5 Bash 退出任务

保存~/.bash_logout在文件中,在退出登录shell式运行
功能:

  • 创建自动备份
  • 清除临时文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值