shell脚本
日常运维工作大部分是一些繁琐的重复的工作,每天80%的工作就是重复干昨天的事情,而且工作量还比较大, 那么摆在运维面前的选择是: A:自己手动搞定一切 B:让机器搞定一切
shell的学习阶段: 1)能看懂shell脚本 2)能改shell脚本 3)能自己写shell脚本 4)能优化shell脚本
shell介绍
shell介绍
shell是一个程序,采用C语言编写,是用户和linux内核沟通的桥梁。它既是一种命令语言,也是一种解释器的编程语言。通过一个图表来看下shell的作用。 拓展知识:
- kernel:为软件服务,接收用户或软件指令驱动硬件,完成工作。
- shell:命令解释器。
- user:用户接口,对接用户。
shell功能
- 命令行解释功能
- 启动程序
- 输入输出重定向
- 管道连接
- 文件名置换(echo /*)
- 变量维护
- 环境控制
- shell编程
shell脚本语法
shell脚本就是将完成一个任务的所有的命令按照执行的先后顺序,自上而下写入到一个文本文件中,然后给予执行权限。
如何抒写shell脚本
shell脚本的命名:
名字要有意义; 文件要有扩展名,建议使用.sh结尾; 名字不要太长,建议30字节以内解决。
shell脚本格式:
shell脚本开头必须制定脚本运行环境以#! 这个特殊符号组合来组成。如:#!/bin/bash 指定该脚本是运行解析由/bin/bash来完成的: shell中的注释使用# 号
shell脚本中,最好加入脚本说明字段: #1)定义脚本的执行环境 #!/usr/bin/bash #2)脚本信息 #Author:bai #Created Time:xxxx-xx-xx xx:xx #Release:1.0 #Script Description : nginx intstall script #4)脚本组成 #解释环境 #!/usr/bin/bash | python | perl #注释说明 #执行代码
shell脚本运行方法
#5)运行脚本 #1. 给执行权限 #2. 解释器直接运行,不需要给权限
Python
vim hello.py
print ("hello world!");
shell中的符号
注意:不要和正则表达式混淆。
~ : 家目录 # cd ~ 代表进入用户家目录 ! :执行历史变量 !! 执行上一条命令 $ :变量中取内容符 + - * % :对应数学运算:加、减、乘、除、取余数 & :后台执行 * :星号是shell中的通配符,匹配所有 ? :问号是shell中的通配符,匹配除回车以外的一个字符 ; :分号可以在shell中一行执行多个命令,命令之间用分号分割 | :管道符,上一个命令的输出作为下一个命令的输入 cat filename | grep “abc” \ :转义字符 ``:反引号,命令中执行命令。echo “today is `date +%F`” ’ ':单引号,脚本中字符串要用单引号引起来,但是不同于双引号的是,单引号不解释变量。 " ":双引号,脚本中出现的字符串可以用双引号引起来
管道
| :管道符在shell中使用是最多的,很多组合命令都要通过组合命令来完成输出,管道符其实就是下一个命令对上一个命令的输出做处理。
重定向
> :重定向输入 ,覆盖原数据 >> :重定向追加输入,在原数据的末尾添加 < :重定向输出 wc -l < /etc/passwd wc < test.txt :输出的是数据流 wc test.txt :输出的是文本 << :重定向追加输出 : ceshi /dev/abc << EOF … EOF
磁盘分区脚本案例
vim disk_partition.sh
fdisk -l
-------------------------------------------
fdisk /dev/sdb <<EOF
n
p
3
+512M
w
EOF
shell脚本中的数学运算
expr 命令:只能做整数运算,格式比较古板,注意空格,必须是整数。 root@mips-01# expr 3 + 3 6 root@mips-01# expr 5 - 2 3 root@mips-01# expr 6 / 2 3 root@mips-01# expr 7 / 2 3 root@mips-01# expr 3 * 39 root@mips-01# expr 9 % 3 0 root@mips-01# expr 9 % 2 1
可以用来判断输入是否为整数:【结合$? 使用】
root@mips-01
4
root@mips-01
0
root@mips-01
expr: 非整数参数
root@mips-01
2
root@mips-01
0
root@mips-01
2
root@mips-01
let 命令和expr 命令都是用来做整数运算的。
root@mips-01
root@mips-01
4
-----------------------------------------
root@mips-01
4
还可以使用bc命令 进行整数和小数的运算
yum -y install bc
bc
[root@bogon ~]
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
3+2
5
4+5
9
100/3
33
141*100/7966
1
4/4
1
(1+1)*3/3
2
小数计算需要设置
scale=2
100/3
33.33
计算内存使用率:
echo "当前内存使用率:`echo "scale=2;141*100/7966"|bc`%"
当前内存使用率:1.77%
使用(( )) 计算:
echo $((1+1))
2
echo $((1-1 ))
0
echo $(( 100*3/2))
150
echo $(( 100%3 ))
1
echo $(( (1+2)*3 ))
9
echo $((10**3))
1000
脚本退出
exit NUM 退出脚本,释放系统资源,NUM代表一个整数,代表返回值。NUM:1-255
格式化输出
一个程序需要有0个或以上输入,一个或更多输出。
echo语法
功能:将内容输出到默认显示设备。 echo命令 的功能是在显示器上显示一段文字,一般起到一个提示的作用。 功能说明:显示文字。 语法: echo [-ne][字符串] 补充说明:echo会将输入的字符串送往标准输出。输出的字符串间以空白字符隔开,并在最后加上换行号。 命令选项: -n :不要在最后自动换行 -e :若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出:转义字符 \a :发出警告声; \b :删除前一个字符;【必须在同一行的字符,配合-n 使用】 \c :最后不加上换行符号; \f:换行但光标仍旧停留在原来的位置; \n:换行且光标移至首行; \r:光标移至首行,但不换行; \t:插入tab; \v:与\f相同; \插入\字符; \nnn:插入nnn(八进制)所代表的ASCII字符; -help:显示帮助; -version:显示版本信息;
------输出内容不换行-----------
echo -n "Login:";read
Login:root
echo -n "Date:";date +%F
Date:2022-03-04
-------让机器输出警告声-----------
echo -e "\a\a\a\a\a\a"
------输出三个换行----------------
echo -e "\n\n\n"
----------删除一个字符------------
echo -n -e "a\b"
---------写一个倒计时脚本----------
vim daojishi.sh
for time in `seq 9 -1 0`;do
echo -n -e "\b$time"
sleep 1
done
echo
--------输出一个水果商店清 单----------
[root@bogon test]
echo -e "\t\t\t\tFruits Shop"
echo -e "\t1) Apple"
echo -e "\t2) Orange"
echo -e "\t3) Banana\n"
echo -n -e "你想吃什么?";read
[root@bogon test]
执行脚本输出如下:
[root@bogon test]
Fruits Shop
1) Apple
2) Orange
3) Banana
你想吃什么?banana
[root@bogon test]
颜色字体
脚本中echo显示内容带颜色显示,echo显示带颜色,需要使用参数-e 格式如下: echo -e "\033[字体背景色; 文字颜色m字符串\033[属性效果m"
eg: echo -e “\033[41;36m something here \033[0m” 其中41的位置代表底色,36的位置代表字的颜色,0的位置代表字体的样式【属性效果】
1、字的背景色和文字颜色之间是英文的"" 2、文字颜色后面有一个m 3、字符串前后可以没有空格,如果有的话,输出也是同样有空格
下面是相应的字和背景颜色,可以自己来尝试找出不同颜色搭配: 字的颜色范围:30-37【黑、红、绿、黄、蓝、紫、天蓝、白】 字的背景色范围:40-47【黑、红、绿、黄、蓝、紫、天蓝、白】
[root@bogon test]
something here
[root@bogon test]
红色字
[root@bogon shell-04]
黄色
[root@bogon shell-04]
黄色
[root@bogon shell-04]
黄色
[root@bogon shell-04]
蓝色
[root@bogon shell-04]
蓝色
[root@bogon shell-04]
[root@bogon shell-04]
红底黑色字
[root@bogon shell-04]
绿色字
[root@bogon shell-04]
紫色字
[root@bogon shell-04]
天蓝字
[root@bogon shell-04]
白色字
[root@bogon shell-04]
字的背景色范围:40-47【黑、红、绿、黄、蓝、紫、天蓝、白】
最后面控制选项说明:
- \033[0m :关闭所有属性
- \033[1m :设置高亮度
- \033[4m :设置下划线
- \033[5m :设置闪烁
- \033[7m :设置反息
- \033[8m :设置消隐
- \033[9m :设置过期线
- \033[30m - \033[37m
设置前景色:
- \033[40n - \033[47m :设置背景色
- \033[nA :光标上移n行
- \033[nB :光标下移n行
- \033[nC :光标右移n行
- \033[nD :光标左移n行
- \033[x;y :设置光标位置
- \033[9m :
- \033[30m - \033[37m
格式化输入
read命令
默认接收键盘的输入,回车符代表输入结束 语法: read 命令选项
- -p :打印信息
- -t :限定时间
- -s :不回显
- -n :输入字符个数
练习:模拟虚拟机的登录界面。
clear
echo -e -n "Centos Linux 7 (Core)\n"
echo -e "kernel `uname -r` an `uanme -m`\n"
echo -n -e "$HOSTNAME login:"
read acc
read -s -p "password:" pw
echo
执行效果:
shell变量
变量介绍
在编程中,我们总是有一些数据需要临时存放在内存,以待后续使用时快速读出。内存在系统启动的时候被按照18个单位划分为若干个块,然后统一编号(16进制编号),并对内存的使用情况做记录,保存在内存跟踪表中。
那么问题来了,1G内存有多少个1B的单位呢?
计算机的单位: 1B = 8bit 1KB = 1024B 1M = 1024KB 1GB = 1024MB 1TB = 1024GB 1PB = 1024TP 1EB = 1024PB 1ZB = 1024EB … 好了,已经够大了!当然还有YB、BB更大的单位,同样进制也是1024. 1G = 102410241024-10737418248
假如你将一个1B的字符存入内存,如何读出呢?有没有一种大海捞针的感觉啊!,我们讨论一下计算机是如何通过让我们人类快速将数据提取在内存,如何从内存中读取数据的。我们研究过变量后就明白了。
变量:变量时编程中最常用的一种临时在内存中取数据的一种方式。 变量存取原理: 从图片可以看出,当我们在定义变量存值的时候,可以从以下方面看到变化:
- 1)内存占用:如果存的是一个字符则占用1个字节,如果存的是字符串则是字符串的长度加1个字节长度(\0是一个特殊字符,代表字符串结束)。
- 2)变量名与内存空间关系:计算机中会将对应的内存空间和变量名称绑定在一起,此时代表这段内存空间已经被程序占用,其他程序不可复用;然后将变量名对应在对应内存地址的空间里。
变量分类
**本地变量:**用户私有变量,只有用户可以使用,保存在家目录下的,bash_profile、bashrc文件中。 **全局变量:**所有用户都可以使用,保存在/etc/profile、/etc/bashrc文件中。 **临时变量:**只作用域本终端,在关闭终端界面或者关机以后就被释放。 **用户自定义变量:**用户自定义,比如脚本中的变量。
变量管理
定义变量
变量格式:变量名=值 在shell编程中 的变量名和等号之间不能有空格 。
变量名命名规则:
- 命名只能使用英文字母、数字和下划线,首个字符不能以数字开头。
- 变量名中间中间不能有空格,可以使用下划线(_)。
- 不能使用标点符号。
- 不能使用bash里的关键字(可用help命令查看保留关键字)。
VAR1=1 age=8 name=‘baism’ score=88.8 注意:字符串要用单引号或双引号引起来
定义变量演示:
[root@arm-00 ~]
[root@arm-00 ~]
[root@arm-00 ~]
读取变量内容
读取变量内容符:$ 变量内容读出:
[root@arm-00 ~]
baism
[root@arm-00 ~]
8
[root@arm-00 ~]
88.8
取消变量unset
[root@arm-00 ~]
[root@arm-00 ~]
[root@arm-00 ~]
shell数组
数组介绍
一个变量只能存在一个值,但是现实中又有很多值需要存储,那么变量就有些拘谨了。比如做一个学员信息表,一个班级有50个人,每个人有6条信息,我们需要定义300个变量才能完成。恐怖,这只是一个班级的学生,一个学校呢?一个市呢?。。。 仔细想想上述的案例,一个学生有6个信息:ID、姓名、性别、年龄、成绩、班级。可不可以定义六个变量就能存储这六类信息呢?答案是肯定的。变量不行,可以用数组。
基本数组
数组可以让用户一次赋予多个值,需要读取数据时只需要通过索引调用就可以方便读出了。
数组的语法
数组名称=(元素1 元素2 元素3 ...)
数组读出
${数组名称[索引]}
索引默认是元素在数组中的排队编号,默认第一个从0开始
eg: echo ${ARRAY1[2]}
数组赋值
方法一:一次赋一个值 ARRAY1[0]=‘2’ ARRAY1[1]=‘F’ ARRAY1[2]=‘4’ ARRAY1[3]=‘tom’ 方法二:一次赋多个值 ARRAY1=(‘A’ ‘B’ ‘C’ ‘D’ ‘4’) ARRAY2=(tom jack alice) ARRAY3=(`cat /etc/passwd) 希望是将文件中的每一个行作为一个元素赋值给数组array3 ARRAY4=(\ ls /var/ftp/Shell/for*`) ARRAY5=(tom jack alice “bash shell”)
查看数组
declare -a :可以查看声明过的数组。
[root@arm-00 test]$ declare -a
declare -a BASH_ARGC='()'
declare -a BASH_ARGV='()'
declare -a BASH_LINENO='()'
declare -a BASH_SOURCE='()'
declare -ar BASH_VERSINFO='([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="aarch64-redhat-linux-gnu")'
declare -a DIRSTACK='()'
declare -a FUNCNAME='()'
declare -a GROUPS='()'
declare -a PIPESTATUS='([0]="0")'
访问数组元素
echo ${array1[0]} :访问数组中的第一个元素 echo ${array1[@]} :访问数组中所有元素,等同于echo ${array1[*]} echo ${#array1[@]} :统计数组中的元素个数 echo ${!array2[@]} :获取数组元素的索引 echo ${array1[@]:1} :从数组下标1开始 echo ${array1[@]:1:2} :从数组下标1开始,访问两个元素。
遍历数组
默认数组通过数组元素的个数进行遍历 echo ${array1[0]} echo ${array1[1]} echo ${array1[2]} echo ${array1[3]}
方法二: 针对关联数组可以用过数组元素的索引进行遍历。
关联数组
关联数组可以允许用户自定义数组的索引 ,这样使用起来更加方便、高效。
定义关联数组
声明关联数组变量 declare -A ass_array1 declare -A ass_array2
[root@bogon shell-05]
baidu
30
[root@bogon shell-05]
declare -A ass_array1
ass_array1[name]='baidu'
ass_array1[age]='30'
echo ${ass_array1[name]}
echo ${ass_array1[age]}
[root@bogon shell-05]
关联数组赋值
方法一:一次附一个值 数组名[索引]=变量值 ass_array1[index1]=pear ass_array1[index2]=apple ass_array1[index3]=orange ass_array1[index4]=peach
方法二:一次附多个值 数组名=([索引1]=变量值 [索引2]=变量值 [索引3]=变量值 [索引4]=变量值) ass_array2=([index1]=tom [index2]=jack [index3]=java [index4]=‘bash shell’)
[root@bogon shell-05]
java
[root@bogon shell-05]
declare -A ass_array2=([index1]=tom [index2]=jack [index3]=java [index4]='bash shell')
echo ${ass_array2[index3]}
[root@bogon shell-05]
访问数组元素
echo ${ass_array2[index2]} :访问数组中第二个元素 echo ${ass_array2[@]} :访问数组中所有元素,等同于echo ${array1[*]} echo ${#ass_array2[@]} :获得数组元素的个数 echo ${!ass_array2[@]} :获取数组元素的索引
遍历数组
通过数组元素的索引进行遍历,针对关联数组可以通过数组元素的索引进行遍历
[root@bogon shell-05]
bash shell
[root@bogon shell-05]
java
[root@bogon shell-05]
jack
[root@bogon shell-05]
tom
[root@bogon shell-05]
案例分享
[root@bogon shell-05]
for ((i=0;i<3;i++))
do
read -p "输入第$((i + 1))个人名:" name[$i]
read -p "输入第$[$i + 1]个年龄:" age[$i]
read -p "输入第`expr $i + 1`个性别:" gender[$i]
done
clear
echo -e "\t\t\t\t学员信息查询系统"
while :
do
cp=0
read -p "输入要查询的姓名:" xm
[ $xm == "Q" ]&&exit
for ((i=0;i<3;i++))
do
if [ "$xm" == "${name[$i]}" ];then
echo "${name[$i]} ${age[$i]} ${gender[$i]}"
cp=1
fi
done
[ $cp -eq 0 ]&&echo "not fonud student"
done
[root@bogon shell-05]
|