**
shell的课程大纲
**
01)Shell基本概述
02)Shell变量定义
03)Shell数值运算
04)Shell流程控制
05)Shell循环语句
06)Shell数组函数
07)Shell内置命令
08)Shell正则表达式
01) shell的基本概述
[root@web01 ~]# echo $-
himBH
h hashall 缓存,命令的路径
i 交互式shell
m 监控
B 大括号扩展
H history
[root@web01 ~]# vim test.sh
#!/bin/bash
echo $-
[root@web01 ~]# sh test.sh
hB
[root@web01 ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
02) shell的种类
[root@web01 ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
[root@web01 ~]# echo $SHELL
/bin/bash
3. 什么是Shell脚本 ?
01)系统的命令堆积在一起,按照顺序执行。
02)特定的格式 + 特定的语法 + 系统的命令 = 文件
03)以.sh为结尾的文件
04) 为什么要学习shell
重复性的工作
自动化的脚本
提高工作效率
05) 如何学好shell编程
01)阅读、模仿、阅读、模仿
02)核心:多练-多思考-再练-再思考-坚持如此循环即可
03)掌握Shell脚本的各种常见语法
04)形成自己的脚本开发风格
05)从简单做起,简单判断,简单循环
06)多模仿、多离开参考资料练习、多思考
07)学会分析问题,逐渐形成编程思维
08)编程变量名字规范,采用驼峰语法表示
09)不要拿来主义,特别针对新手
06) 学习Shell编程需要哪些知识 ?
01)对vim编辑器能熟练使用,熟悉SSH终端及".vimrc"等的配置。
02)要有一定的Linux命令基础,至少掌握80个以上Linux常用命令并能熟练使用。
03)要熟练掌握Linux正则表达式以及三剑客命令(grep、sed、awk)。
04)熟悉常见的Linux网络服务部署、优化、日志分析及排错。
07) Shell脚本能做什么 ?
01)基础配置:系统初始化操作、系统更新、内核调整、网络、时区、SSH优化等。
02)安装程序:LNMP、LAMP、MySQL、Nginx、Redis等。
03)配置变更:Nginx Conf、PHP Conf、MySQL Conf、Redis Conf等。
04)业务部署:Shell配合Git、Jenkins实现自动化部署PHP、Java代码,以及代码回滚。
05)日常备份:MySQL全备 + 增量 + binlog + crond + Shell脚本备份等。
06)信息采集:Zabbix + Shell: 对硬件、系统、服务、网络的监控等。
07)日志分析:ELK:取值->排序->去重->统计->分析等。
08)服务扩容/缩容:Zabbix + Shell
扩容: 监控服务器cpu, 如cpu负载持续80% + 触发动作(脚本)
脚本: 调用api开通云主机->初始化环境->加入集群->对外提供访问
缩容: 监控服务器cpu使用率20%->判断有多少web节点->判断是否超过预设->缩减到对应的预设状态->变更负载的配置
01)脚本放在放在统一的目录
mkdir -p /shell/
02)推荐使用vim编辑器编辑脚本(高亮显示)
03)以.sh为扩展名
04)规范的Shell脚本第一行会指出由哪个程序(解释器)来执行脚本中的内容。
#!/bin/bash 或 #!/bin/sh #如不指定Shell,默认以bash执行。
05)开头的"#!“称为幻数,在执行Shell脚本的时候,内核会根据”#!"后的解释器来确定使用哪个程序解释脚本中的内容。注意:这一行必须在每个脚本顶端的第一行,如果不是第一行则为脚本注释行。
06)附带作者及版权信息。
07)脚本注释:在Shell脚本中,跟在"#"后面的内容表示注释。注释部分不会被执行,仅给人看。注释可以自成一行,也可以跟在命令后面,与命令同行。要养成写注释的习惯,方便自己与他人。最好不用中文注释,因为在不同字符集的系统会出现乱码。
08)成对的符号一次书写完成。
09)循环的格式一次书写完成。
shell 的执行方式
[root@web01 shell]# vim test.sh
#!/bin/bash
pwd
#新打开一个shell窗口执行,不需要执行权限
[root@web01 shell]# sh test.sh
/shell
[root@web01 shell]# bash test.sh
/shell
#使用绝对路径或者相对路径执行,需要执行权限。另起一个窗口
[root@web01 shell]# /shell/test.sh
-bash: /shell/test.sh: Permission denied
[root@web01 shell]# ./test.sh
-bash: ./test.sh: Permission denied
[root@web01 shell]# chmod +x ./test.sh
[root@web01 shell]# /shell/test.sh
/shell
[root@web01 shell]# ./test.sh
/shell
将脚本内容调用到当前窗口执行
[root@web01 shell]# vim test.sh
#!/bin/bash
ping baidu.com
[root@web01 shell]# source test.sh
PING baidu.com (220.181.38.148) 56(84) bytes of data.
64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=1 ttl=128 time=27.7 ms
64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=2 ttl=128 time=26.4 ms
64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=3 ttl=128 time=27.3 ms
将脚本内容调用到当前窗口执行
[root@web01 shell]# cat test.sh | bash
PING baidu.com (39.156.69.79) 56(84) bytes of data.
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=128 time=29.4 ms
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=128 time=30.3 ms
[root@web01 shell]# bash < test.sh
PING baidu.com (39.156.69.79) 56(84) bytes of data.
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=128 time=34.2 ms
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=128 time=29.3 ms
登录shell:是需要用户名、密码登录后才能进入的Shell。
非登录shell:当然就不需要输入用户名和密码即可打开的Shell,例如:直接命令"bash"就是打开一个新的非登录Shell,在Gnome或KDE中打开一个"终端"(terminal)窗口程序也是一个非登录Shell。
exit
logout
什么变量
命名规范
定义方式
自定义
[root@web01 shell]# name=gaozhiwei #定义变量
[root@web01 shell]# echo $name #显示变量
gaozhiwei
[root@web01 shell]# echo ${name}
gaozhiwei
[root@web01 shell]# echo $nameage
[root@web01 shell]# echo ${name}age
gaozhiweiage
[root@web01 shell]# set |grep name #显示系统中的所有变量
name=gaozhiwei
[root@web01 shell]# env |grep name #显示系统中的环境变量
[root@web01 shell]# unset name #取消变量
[root@web01 shell]# echo $name
单双引号和不加引号及反引号的区别
[root@web01 shell]# echo $name
web01
[root@web01 shell]# echo my name is web01 moneny is $10000000000
my name is web01 moneny is 0000000000
[root@web01 shell]# echo my name is $name moneny is $10000000000
my name is web01 moneny is 0000000000
[root@web01 shell]# echo 'my name is $name moneny is $10000000000'
my name is $name moneny is $10000000000
[root@web01 shell]# echo "my name is $name moneny is $10000000000"
my name is web01 moneny is 0000000000
[root@web01 shell]# echo "my name is $name moneny is \$10000000000"
my name is web01 moneny is $10000000000
[root@web01 shell]# echo my name is $name moneny is \$10000000000
my name is web01 moneny is $10000000000
[root@web01 shell]# echo 'my name is $name moneny is \$10000000000'
my name is $name moneny is \$10000000000
单引号 所见即所得,会把引号中的内容看做是一个整体。
双引号 所见即所得,会把引号中的内容看做是一个整体。会解析变量。
不加引号 所见即所得,如果出现空格,并不会把他看做是一个整体,会解析变量。
反引号 先执行里面的命令,把结果交出来 和$()同义。
系统定义
环境变量,主要定义系统中的系统信息
[root@web01 shell]# name=web02
[root@web01 shell]# echo $name
web02
[root@web01 shell]# sh test.sh
[root@web01 shell]# export name=web02
[root@web01 shell]# sh test.sh
web02
在所有窗口生效
如果想要永久生效,写入到配置文件中
预定义
[root@web01 shell]# vim 1.sh
#!/bin/bash
echo "#当前shell脚本的文件名: $0"
echo "#第1个shell脚本位置参数:$1"
echo "#第2个shell脚本位置参数:$2"
echo "#第3个shell脚本位置参数:$3"
echo "#所有传递的位置参数是: $*"
echo "#所有传递的位置参数是: $@"
echo "#总共传递的参数个数是: $#"
echo "#当前程序运行的 PID 是: $$"
echo "#上一个命令执行的返回结果: $?"
[root@web01 shell]# sh 1.sh linux shell mysql
#当前shell脚本的文件名: 1.sh
#第1个shell脚本位置参数:linux
#第2个shell脚本位置参数:shell
#第3个shell脚本位置参数:mysql
#所有传递的位置参数是: linux shell mysql #会将结果看做是一个整体显示出来
#所有传递的位置参数是: linux shell mysql
#总共传递的参数个数是: 3
#当前程序运行的 PID 是: 7351
#上一个命令执行的返回结果: 0
位置变量
1...... 1...... 1......N ${10}
[root@web01 shell]# vim read-1.sh
#!/bin/bash
read -p "请输入一个值:" var
echo "你输入的值为 $var"
简单备份目录
#!/bin/bash
read -p "请输入你要备份的目录:" dir
echo "你要备份的目录为: $dir"
echo "------------------------------"
echo "备份目录$dir starting"
echo "------------------------------"
echo "目录 $dir done"
read示例
测试用户输入的IP是否通
方法一
[root@web01 shell]# vim read-3.sh
#!/bin/bash
#1.请用户输入一个ip地址
read -p "请输入一个你要测试连接的ip地址:" Ip
#2.进行测试该用户输入的ip地址是否连通
ping -W1 -c1 $Ip &>/dev/null && echo "该$Ip 地址是通的" || echo "该$Ip 地址是不通的"
方法二
[root@web01 shell]# vim read-3.sh
#!/bin/bash
#1.请用户输入一个ip地址
read -p "请输入一个你要测试连接的ip地址:" Ip
#2.进行测试该用户输入的ip地址是否连通
ping -W1 -c1 $Ip &>/dev/null
#3.判断上条命令的执行结果
if [ $? -eq 0 ];then
echo "该$Ip地址是通的"
else
echo "该$Ip地址是不通的"
fi
echo特性
#echo命令输出颜色。
echo -e "\033[30m 黑色字 \033[0m"
echo -e "\033[31m 红色字 \033[0m"
echo -e "\033[32m 绿色字 \033[0m"
echo -e "\033[33m 黄色字 \033[0m"
echo -e "\033[34m 蓝色字 \033[0m"
echo -e "\033[35m 紫色字 \033[0m"
echo -e "\033[36m 天蓝字 \033[0m"
echo -e "\033[37m 白色字 \033[0m"
[root@web01 shell]# vim read-3.sh
#!/bin/bash
#1.请用户输入一个ip地址
read -p "请输入一个你要测试连接的ip地址:" Ip
#2.进行测试该用户输入的ip地址是否连通
ping -W1 -c1 $Ip &>/dev/null
#3.判断上条命令的执行结果
if [ $? -eq 0 ];then
echo -e "\033[32m 该$Ip地址是通的 \033[0m"
else
echo -e "\033[31m 该$Ip地址是不通的 \033[0m"
fi
使用read命令写一个脚本修改主机名
1.使用read提示用户输入新的主机名
2.是否确认修改主机名为新的主机名 提示用户输入 Y N
3.根据用户输入的Y或N进行判读
4.如果是Y,则修改。否则退出
[root@web01 shell]# vim read-4.sh
#!/bin/bash
#1.提示用户要修改之后的新的主机名
read -p "请输入你要修改之后的主机名:" New
#2.友好提示,是否确认修改
read -p "请确认是否修改主机名为 $New ,请输入[Y|N]:" con
#3.根据用户输入的Y或N进行判断,如果是Y,则修改,否则就不修改退出。
if [ $con == "Y" ];then
hostnamectl set-hostname $New && echo "hostname更新成功!"
bash
else
echo "你选择的是不修改,脚本退出!"
exit
fi
使用read写一个修改ip地址的脚本
[root@shell shell]# cat read-5.sh
#!/bin/bash
#1.请用户输入修改之后的ip地址的主机位
read -p "请输入你要修改之后的IP地址的主机位:" Ip
#2.友好提示,是否确认修改
read -p "你修改之后的ip地址主机位为:$Ip ,是否确认修改[Y|N]:" con
#3.判断用户输入的是Y还是N,如果是Y,则修改,否则退出。
if [ $con == "Y" ];then
#5.修改ip地址
sed -ri "s#(^IPA.*\.).*#\1$Ip#g" /etc/sysconfig/network-scripts/ifcfg-eth[01] && echo "IP地址修改成功"
#6.友好提示,主机名修改成功,是否确认重启网络服务进行生效。
read -p "是否确认重启网卡进行生效。请确认[Y|N]:" red
#根据用户输入的值进行判断,是否重启网卡
if [ $red == "Y" ];then
echo "网卡重启之后,该连接会断开,成功之后请使用新的ip地址进行连接。"
systemctl restart network
else
echo "你没有选择进行重启网卡服务,你可以手动重启,再见!"
exit
fi
else
echo "你选择不修改IP地址,再见!"
exit
fi
shell变量替换
变量 说明
${#变量} 获取变量值的长度
${变量#匹配规则} 从头开始匹配,最短删除
${变量##匹配规则} 从头开始匹配,最长删除
${变量%匹配规则} 从尾开始匹配,最短删除
${变量%%匹配规则} 从尾开始匹配,最长删除
${变量/旧字符串/新字符串} 替换变量内的旧字符串为新字符串,只替换第一个
${变量//旧字符串/新字符串} 替换变量内的旧字符串为新字符串,全部替换
${变量:匹配规则:匹配规则} 索引及切片
[root@shell shell]# url=www.oldboyedu.com.cn
[root@shell shell]# echo ${#url}
20
[root@shell shell]# echo ${url#*.}
oldboyedu.com.cn
[root@shell shell]# echo ${url##*.}
cn
[root@shell shell]# echo ${url%.*}
www.oldboyedu.com
[root@shell shell]# echo ${url%%.*}
www
[root@shell shell]# echo ${url/o/O}
www.Oldboyedu.com.cn
[root@shell shell]# echo ${url//o/O}
www.OldbOyedu.cOm.cn
[root@shell shell]# echo ${url:5:5}
ldboy
[root@shell shell]# echo ${url:0:3}
www
[root@shell shell]# echo ${url:3}
.oldboyedu.com.cn
**加粗样式**监控内存的使用率,如果使用率大于80%,则报警,否则正常
```powershell
root@shell shell]# cat use_free.sh
#!/bin/bash
#1.定义内存使用率的值的变量
Use_Free=$(free -m |awk '/^Mem/{print $3/$2*100}')
#2.判断使用率大于80%,则进行报警。
if [ ${Use_Free%.*} -ge 80 ];then
echo "当前内存使用率过大,使用率为:${Use_Free}%"
else
echo "当前内存使用率正常!"
exit
fi
在每月第一天备份并压缩/etc目录的所有内容,存放到/root/bak目录,存放的形式 2019-06-20_etc.tar.gz,脚本名称为fileback。
[root@shell shell]# vim fileback.sh
#!/bin/bash
#定义变量
Date=$(date +%F)
Bak_Dir=/root/bak
#2.判断目录是否存在,存在则不创建,不存在则创建目录
[ -d $Bak_Dir ] || mkdir -p $Bak_Dir
#3.进行备份
tar czf $Bak_Dir/${Date}_etc.tar.gz /etc && echo "/etc/目录备份成功!" || echo "/etc/目录备份失败"
在/backup下创建10个.txt的文件,找到/backup目录下所有后缀名为.txt的文件
1)批量修改txt为txt.bak
2)把所有的.bak文件打包压缩为123.tar.gz
3)批量还原文件的名字,及把增加的.bak再删除
取出下列字符串长度小于3的单词,I am qiuzengjia teacher I am 18。
(http://www.baidu.com)*[HTML]: 超文本标记语言