shell编程
shell编程
最基本要求:
1.了解Shell的基本语法结构
数组 条件判断 循环控制 分支语句 函数
2.了解正则表达式的运用
3.学习文本处理工具cut、awk、sed等
4.可以使用Shell完成一些较为复杂的任务(服务搭建、批量文件处理、脚本工具等)
一、shell介绍
1.1 Shell是什么?
定义:shell是一个命令解释器
a)shell位于操作系统和应用程序之间,是他们二者的接口,负责:把应用程序的输入命令信息解释给操作系统,将操作系统指令处理后的结果解释给应用程序。
b)Shell还是一个功能相当强大的解释性编程语言,易编写、易调试、灵活性强。
1.2 语言类型
a)编译型语言:程序在执行之前需要一个专门的编译过程,把编译过程编译成为机器语言文件,运行时不需要重新翻译,直接使用编译的结果就行了。程序执行效率高,依赖编译器,跨平台性差些。如C++、C语言
b)解释性语言:程序不需要编译,程序在运行时由解释器翻译成机器语言,每执行一次都要翻译一次。因此效率较低。比如Phtyon/JavaScript/ruby/Shell等都是解释性语言
总结:
编译型语言比解释型语言速度较快,但是不如解释型语言跨平台性好。
如果做底层开发或者大型应用程序或者操作系开发一般都用编译型语言;如果是一些服务器脚本及一些辅助的接口,对速度要求不高、对各个平台的兼容性有要求的话则一般都用解释型语言。
说明:
说明:Java无法用编译型或者解释型来划分语言类型,可以说Java是编译型的。因为所有的Java代码都是要编译的,.java不经过编译就无法执行。 也可以说Java是解释型的。因为java代码编译后不能直接运行,它是解释运行在JVM上的,所以它是解释型的。
1.3 Shell解析器
a)、bash也就是 Bourne Again Shell,由于易用和免费,bash 在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的 Shell。
b)、sh和bash的关系
二、shell作用
2.1 Shell脚本
a)若干命令+脚本的基本格式+脚本特定语法+思想= shell脚本,脚本按照顺序执行(由上往下执行),它是解释型的,不需要编译。
2.2 使用场景
b)重复化、复杂化的工作,可以写成脚本,以后只需要执行脚本就可以完成这些工作
2.3 Shell脚本能干什么?
①自动化软件部署
②自动化分析处理
③自动化分析处理
④自动化备份
⑤自动化监控脚本
三、Shell怎么用
3.0 脚本格式
part1:第一行指定解析器:脚本以#!/bin/bash 或 #!/bin/evn bash 开头
part2:第二行开始编写脚本的基本信息描述
part3:脚本的具体代码内容
3.1 创建一个Shell脚本,输出helloword
3.2 运行方式
a)case1:采用bash或sh + 脚本的相对路径或绝对路径(不用赋予脚本+x权限)
sh/bash 绝对路径|相对路径
source 绝对路径|相对路径
b)case2:采用输入脚本的绝对路径或相对路径执行脚本(必须有可执行权限+x,推荐采用这种方式)
赋予脚本的+x权限
chmod +x 脚本名称
运行: ./脚本名称
如果需要在任意地方执行脚本,需要将脚本移动至/bin目录
运行: 脚本名称
3.3 查看脚本的执行流程
bash -x 脚本名称
3.4 查看脚本的语法错误
bash -n 脚本名称
四、Shell变量
4.1 作用:变量是用来临时保存数据的,该数据是可以变化的
4.2 什么时候用?
a)多次使用,在代码中重复出现,这样在修改内容的时候,仅仅需要改变量的值
b)代码运作的过程中,后续代码需要使用某些命令的执行结果,可以使用变量保存执行结果
4.3.1 获取Shell中的所有变量命令:set
4.3.2 获取环境变量命令:env
4.4 系统变量:
a) H O M E 、 HOME、 HOME、PWD、 S H E L L 、 SHELL、 SHELL、USER
b) 读取变量:echo $变量名
经验技巧:
(1)变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
(2)等号两侧不能有空格
(3)在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。
(4)变量的值如果有空格,需要使用双引号或单引号括起来。
4.5 自定义变量
a)用户变量 (作用域:只在当前会话的用户下有效)
①定义变量
变量名=值
变量名=执行命令
变量名=$(执行命令)
②读取变量:echo $变量名
echo ${A:2:3}
echo ${A}
echo$A
③撤销变量: unset 变量名
④静态变量 :(一旦创建,只可读,不能unset):readonly 变量名=值
⑤定义有类型的变量
目的:给变量做一些限制,固定变量的类型
语法:declare 选项 变量名=变量值
常用选项:-i 将变量看作整数; -r创建只读变量
b)全局环境变量 (作用域:针对于当前会话下的所有用户有效)
关键字:export
定义变量:export 变量名=值
撤销和读取同上
c)系统环境变量 (作用域:针对于所有会话下的所有用户都有效)
编辑配置文件:vim /etc/profile
例如添加系统环境变量 MYNAME=jinghang
#系统环境变量 export MYNAME=jinghang
变量生效 source /etc/profile
4.6 特殊变量
a) n 语 法 : n 语法: n语法:n (功能描述:n为数字,$0代表该脚本名称,$1- 9 代 表 第 一 到 第 九 个 参 数 , 十 以 上 的 参 数 , 十 以 上 的 参 数 需 要 用 大 括 号 包 含 , 如 9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如 9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如{10})
b) KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲ 语法:# (功能描述:获取所有输入参数个数,常用于循环)
c) ∗ 语 法 : * 语法: ∗语法:* (功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体)
d) @ 语 法 : @ 语法: @语法:@ (功能描述:这个变量也代表命令行中所有的参数,不过[email protected]把每个参数区分对待)
e) ? 语 法 : ? 语法: ?语法:? (功能描述:最后一次执行命令的返回状态。如果值为0,命令正确执行;如果值为非0(具体是哪个数,由命令自己来决定),则命令执行不正确)
五、Shell数组
5.1 定义:Shell 数组用括号来表示,元素用"空格"符号分割开,如果元素中包含空格,则该元素使用双引号引起来,例如"hello word"
5.2 语法:数组名=(value1 value2 value3)
5.3 赋值:创建时添加 my_array=(A B “C B” D) 创建时添加my_array[4] =E
5.4 修改:局部:根据索引修改数组 my_array[0]=F 整体:可以直接给数组变量重新赋值
5.5 读取:
①获取数组中所有的元素:echo ${数组名[*]} | echo ${数组名[@]}
②根据索引读取数组元素:echo ${数组名[索引值]}
③获取数据组的长度:echo ${#数组名[*]} | echo ${#数组名[@]}
5.6 删除:
①unset 关键字来删除数组元素,格式如下:
unset array_name[index]
②不写下标,删除整个数组,格式如下:
unset array_name
5.7 遍历数组案例:
输出的结果:
六、Shell中的运算符
6.1 整数运算语法:
(1)“ ( ( 运 算 式 ) ) ” 或 “ ((运算式))”或“ ((运算式))”或“[运算式]” + , - , *, /, % 加,减,乘,除,取余
(2)expr + , - , *, /, % 加,减,乘,除,取余
注意:expr运算符间要有空格
6.2 案例:
6.3 小数运算:
bc:Linux下的一个计算器程序,可以处理整数和小数。Shell 本身只支持整数运算,想计算小数就得使用 bc 这个外部的计算器
在 Shell 脚本中,借助管道或者输入重定向来使用 bc 计算器。
语法:echo “scale=小数位数 ; expression” | bc
expression就是希望计算的数学表达式
案例1:计算3*8/7 结果保留4位小数
案例2:计算3*8/7 ,再乘5,结果保留3位小数
案例3:计算4/9,保留2位,结果赋值给ret变量
七、Shell条件判断
7.1 语法:[ condition ](注意condition前后要有空格)
注意:条件非空即为true,[ jinghang ]返回true,[] 返回false
(1)两个整数之间比较
== 字符串比较
-lt 小于(less than)
-le 小于等于(less equal)
-eq 等于(equal)
-gt 大于(greater than)
-ge 大于等于(greater equal)
-ne 不等于(Not equal)
7.2 常用条件判断
(2) 按照文件权限进行判断
-r 有读写的权限(read)
-w 有写的权限 (write)
-x 有执行的权限 (execute)
(3)按照文件类型进行判断
-f 文件存在并且是一个常规的文件 (file)
-e 文件是否存在 (existence)
-d 文件存在并是一个目录 (directory)
7.3 实操案例:
(1)23是否大于等于22
(2)判断文件是否具有写权限
(3)判断目录中的文件是否存在
(4)多条件判断(&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一条命令执行失败后,才执行下一条命令)
八、Shell流程控制
8.1 if判断语句
语法1:
if [条件判断式]
then
主体代码
fi
语法2:
if [条件判断式]
then
主体代码
else
主体代码
fi
语法3:
if [条件判断式]
then
主体代码
elif [条件判断式]
then
主体代码
else
主体代码
fi
注意事项:
(1)[ 条件判断式 ],中括号和条件判断式之间必须有空格
(2)if后要有空格
案例1:
编写一个脚本,传入文件或者目录名称
(1)判断文件或者目录是否存在,存在则完成(2)(3)步骤,不存在则输出文件或目录不存在(2)如果是文件输出路径并打印"该路径为文件路径",并往文件中写入 “我爱邓伦”
(3)如果是目录,输出路径并打印"该路径为目录路径",并在该路径下创建bbb.txt文件
案例2:
完成一个脚本,传入两个参数,判断参数大小,用大的减小的,如果相等,则输出两个数值相同
输出结果:
8.2 case 判断语句
基本语法:
case $变量名 in
“值1”)
如果变量的值等于值1,则执行程序1
;;
“值2”)
如果变量的值等于值2,则执行程序2
;;
…省略其他分支…
*)
如果变量的值不是以上的值,则执行此程序
;;
esac
注意事项:
1)case行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。
2)双分号“;;”表示命令序列结束,相当于java中的break。
3)最后的“*)”表示默认模式,相当于java中的default。
案例1:
完成一个脚本
如果传入的数字是1;打印美女,你好
如果传入的数字是2;打印型男,你好啊
如果传入的数字是3;打印讨厌,猥琐男
其他的数字:打印"告诉我你的性别"
输出结果
8.3 for 循环语句
基本语法:
语法:
for ((i=0;i<100;i++))
do
程序
done
写法二
$*:读取传入脚本的全部参数,把参数看作一个整体
[email protected]:读取传入脚本中的全部参数,把参数区分对待
for 变量 in “$*”
do
程序
done
案例1
(1)从1加到100
8.4 while 循环语句
基本语法 :
while [条件判断式]
do
程序
done
注意:While 与 [ 号之间要有空格
8.5 until 循环语句
until 循环执行一系列命令直至条件为 true 时停止
基本语法:
until [条件判断式]
do
程序
done
九、read读取控制台输入
9.1基本语法: read [选项]
选项 功能
-p 指定读取值时的提示符;
-t 指定读取值时等待的时间(秒);
参数:指定读取值的变量名
十、Shell函数
10.1 系统函数
basename
basename 命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来
basename [string / pathname] [suffix]
可选项:suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。
dirname
从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)
dirname 文件绝对路径
10.2 自定义函数
语法:
[ function ] funname()
{
Action;
[return int;]
}
funname
经验技巧
(1)必须在调用函数地方之前,先声明函数,shell脚本逐行运行。不会先编译。
(2)函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)
在用户主目录下找到.bashrc文件,在该文件中添加的函数,只针对与该用户有效
自定义用户函数
在/etc/bashrc,在该文件中添加的函数,只针对于所有用户有效
自定义系统函数
十一、Shell文本处理
11.1 cut 功能描述:cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的,cut指令用户显示行中的指定部分,删除文件中的指定字段。
语法:cut 【选项】 【文件】
选项 功能
-b <起始字节位置-结束字节位置> 仅显示行中指定字节范围的内容。例如,“-b 2-10”将显示第2~10个字节位置的内容,当只有一个数字时,则仅显示指定字符位置的内容.
-f <起始列位置-结束列位置> 显示指定的字段内容
-d <分隔符> 指定字段的分隔符,默认的字段分隔符为“TAB”
-c <起始字符位置-结束字符位置> 仅显示行中指定范围的字符。例如,“-c 2-10” 将显示第2~10个字符位置的内容。当只有一个数字时,则仅显示指定字符位置的内容
11.5 sort 功能描述:它将文件进行排序,并将排序结果标准输出
语法:sort 【选项】 【参数】
选项 说明
-n 依照数值的大小排序
-r 以相反的顺序来排序
-t 设置排序时所用的翻个字符
-k 指定需要排序的文件
参数:是指待排序的文件
11.2 正则表达式
正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE)。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本
单字符匹配
\d 匹配一个数字字符。等价于[0-9]
\D 匹配一个数字字符。等价于[^0-9]
\w 匹配包括下划线的任何单词字符。类似但不等价于[A-Za-z0-9_]
\W 匹配任何非单词字符。等价于 [^ A-Za-z0-9_]
\s 匹配空白字符,包括空格、制表符、换页符等等,等价于[ \f\n\r\t\v]
\S 匹配任何可见字符。等价于[^ \f\n\r\t\v]
.点 匹配除“\n”和"\r"之外的任何单个字符
[a-z] 字符范围,匹配a~z之间的任意字符
[^a-z] 匹配除了a~z之间的其他字符
\n 匹配换行符
多字符匹配
+配前面的子表达式一次或多次(大于等于1次)
*匹配前面的子表达式任意次
? 匹配前面的子表达式零次或一次
{n} n是一个非负整数。匹配确定的n次
{n,m} m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次
其他
^ 匹配输入字行首
$ 匹配输入行尾
| 将两个匹配条件进行逻辑“或”(or) 运算
爬虫,正则
11.3 sed
功能描述:sed是一种单行文本流式编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件结束。文件内容并没有改变,除非你使用重定向存储输出。
语法:sed【选项】‘命令’ 文件名
选项 功能
-e 直接指令列模式上进行sed的动作编辑(一次执行多个操作时)
-i 直接编辑文件
-n 取消默认输出,sed默认会输出所有文本内容,使用-n参数后只显示处理过的行
命令 功能
p 打印一般-n配合使用
a 新增,在指定的行之前插入内容
d 删除
s 查找并替换(注意:如果进行全局的查找替换 sed -i ‘s/查找条件/替换字符/g’ global)
11.4 awk
功能描述:是一门编程语言,也是一个强大的文本分析工具,逐行扫描文件,默认从第一行到最后一行,寻找匹配特定模式的行,并在这些行上进行你想要的操作。
语法:awk 选项 ‘pattern1{action1} pattern2{action2}…’ 文件名
pattern:表示AWK在数据中查找的内容,就是匹配模式
action:在找到匹配内容时所执行的一系列命令
选项 功能
-F 指定输入文件的分隔符
-v 赋值一个用户定义变量
awk 的内置变量
变量 说明
FILENAME 文件名
NR 已读的记录数
NF 浏览记录的域的个数(切割后,列的个数)
文件名
选项 功能
-e 直接指令列模式上进行sed的动作编辑(一次执行多个操作时)
-i 直接编辑文件
-n 取消默认输出,sed默认会输出所有文本内容,使用-n参数后只显示处理过的行
命令 功能
p 打印一般-n配合使用
a 新增,在指定的行之前插入内容
d 删除
s 查找并替换(注意:如果进行全局的查找替换 sed -i ‘s/查找条件/替换字符/g’ global)
11.4 awk
功能描述:是一门编程语言,也是一个强大的文本分析工具,逐行扫描文件,默认从第一行到最后一行,寻找匹配特定模式的行,并在这些行上进行你想要的操作。
语法:awk 选项 ‘pattern1{action1} pattern2{action2}…’ 文件名
pattern:表示AWK在数据中查找的内容,就是匹配模式
action:在找到匹配内容时所执行的一系列命令
选项 功能
-F 指定输入文件的分隔符
-v 赋值一个用户定义变量
awk 的内置变量
变量 说明
FILENAME 文件名
NR 已读的记录数
NF 浏览记录的域的个数(切割后,列的个数)
NR 已读的记录数