01基础 4、Shell 脚本

shell学习目标

1. Shell基本概述

2. Shell的变量定义

3. Shell数值运算
 
4. Shell的流程控制  if语句

5. Shell的循环语句 for  while循环

6. Shell的数组函数

7. Shell内置命令 

8. Shell正则表达式  Awk Grep Sed

Shell

shell概述

1、shell是命令解释器,shell存在Linux系统的最外层,shell连接系统,负责和用户对话,用户输入用户名和密码登陆后的所有输入都由shell解释并执行。

2、shell存在交互式和非交互式
2.1 交互式
#比如,我们用命令 “echo $-” 问 shell 你都有什么功能啊?
[root@shell01 ~]# echo $-
himBH
#shell回答,我有 “himBH” 这些功能
01)h:hashall,打开这个选项后,Shell会将命令所在的路径记录下来,避免每次都要查询。
02)i:interactive,包含这个选项说明当前的Shell是一个交互式的Shell。
03)m:monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等。
04)B:braceexpand,大括号扩展。
05)H:history,Shell会把我们执行的命令记录下来,可以通过history命令查看。
2.2 非交互式,我们把命令 “echo $-” 放到脚本中执行,就是非交互式的
[root@shell01 ~]# vim test.sh
#!/bin/bash
echo $-
[root@shell01 ~]# sh test.sh 
hB
#shell脚本执行结果只有 “hB”

3、shell的作用:减少重复性工作,提高工作效率,实现自动化运维。

4、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节点->判断是否超过预设->缩减到对应的预设状态->变更负载的配置

Shell脚本编写规范

注意:#!/bin/bash 这一行必须在每个脚本顶端的第一行,如果不是第一行则为脚本注释行。
01)以 #!/bin/bash 或 #!/bin/sh 开头,开头的"#!"称为幻数,如不指定Shell,默认以bash执行,在执行Shell脚本的时候,内核会根据"#!"后的解释器来确定使用哪个程序解释脚本中的内容。
02)建立一个目录作为脚本的统一存放位置 mkdir scripts
03)用vim编辑器进行脚本编辑,有不同的颜色高亮显示,便于观察
04)脚本名称要以 .sh 结尾,便于使用
05)建议脚本中写上注释行,用来注明脚本中命令行的作用,建议用英文编写
06)编写脚本时,成对的符号一定要一次写完,再写符号内的内容,循环格式一次性写完
07)在需要退出的地方可以增加 exit 命令退出脚本
#!/bin/bash
if [[ 满足条件1 ]]; then
	执行这里的命令
elif [[ 满足条件2 ]]; then
	执行这里的命令
else
	exit #主动退出脚本,不再执行后面的脚本内容
fi

Shell的执行方式

脚本从上到下 从左到到右的方式进行执行,脚本执行时遇到子脚本,会执行子脚本,子脚本执行完成后,退出子脚本,继续执行脚本中的内容。

脚本运行时,会向系统内核请求一个进程。脚本就会在该进程下进行运行,终止操作。

#创建一个脚本
[root@shell01 /scripts]# echo "pwd"  >test.sh
[root@shell01 /scripts]# cat test.sh 
pwd
[root@shell01 /scripts]# ll
total 4
-rw-r--r-- 1 root root 4 2020-02-19 11:10 test.sh

#脚本执行方法
#必须要有执行权限
1、path/script-name(绝对路径)  或者  ./script-name
[root@shell01 /scripts]# chmod u+x test.sh 
[root@shell01 /scripts]# ll
total 4
-rwxr--r-- 1 root root 4 2020-02-19 11:10 test.sh
[root@shell01 /scripts]# /scripts/test.sh 
/scripts
[root@shell01 /scripts]# ./test.sh 
/scripts

#不需要执行权限
#脚本运行时,会向系统内核请求一个进程。脚本就会在该进程下进行运行。
1. bash script-name  或者  sh script-name
[root@shell01 /scripts]# bash  test.sh
/scripts
[root@shell01 /scripts]# sh  test.sh
/scripts

#无需执行权限,将脚本中的命令调入到当前环境下执行,这种情况下脚本中的语法并不全部适合当前的命令行语法规范,会出现错误提示,不建议使用.
3. source  script-name  或者  . script-name
4. cat script-name  | bash
5. bash  < script-name

shell变量

1、变量定义
#一般定义变量用大写字母,如果有2个相邻的变量,建议用空格或花括号隔开
[root@dev01 ~]# echo $a $b
1 2
[root@dev01 ~]# echo ${a}$b
12

#定义单个变量
[root@dev01 ~]# a=1				#为变量 a 赋值
[root@dev01 ~]# b=2				#为变量 b 赋值
[root@dev01 ~]# echo $a_$b		#不加引号:中间如果是+-*/@#%^&或者空格都可以显示出2个变量内容
2
[root@dev01 ~]# echo '$a'_$b	#单引号:强引用,里面是什么,就输出什么
$a_2
[root@dev01 ~]# echo "$a"_$b	#双引号:弱引用,吃什么吐什么,会解析变量
1_2
[root@dev01 ~]# echo `$a`_$b	#反引号 ``:优先执行反引号里面的命令 跟  $() 含义一样
-bash: a: command not found
_2

#变量内容定义为多个变量
[root@dev01 ~]# c=${a}_$b
[root@dev01 ~]# echo $c
1_2

#变量内容定义为命令
[root@dev01 ~]# d=$(pwd)
[root@dev01 ~]# echo $d
/root
2、变量取值
变量 说明
${#变量} 获取变量的长度
${变量#匹配规则} 从头开始匹配,最短删除,第一次匹配到哪里就删除到哪里
${变量##匹配规则} 从头开始匹配,最长删除,最后匹配到哪里就删除到哪里
${变量%匹配规则} 从尾开始匹配,最短删除,第一次匹配到哪里就删除到哪里
${变量%%匹配规则} 从尾开始匹配,最长删除,最后匹配到哪里就删除到哪里
${变量/旧的字符串/新的字符串} 替换变量中的旧的字符串为新的字符串,只替换第一个
${变量//旧的字符串/新的字符串} 替换变量中的旧的字符串为新的字符串,替换所有
${变量:匹配规则:匹配规则} 索引及切片
#变量替换实战
[root@shell /scripts]# url=www.sina.com.cn		#定义变量
[root@shell /scripts]# echo $url				#打印变量
www.sina.com.cn
#取出变量长度
[root@shell /scripts]# echo ${#url}				#获取变量值的长度
15
#从头删除
[root@shell /scripts]# echo ${url#*.}		#从头开始匹配,最短删除,*表示所有,点没有任何含义
sina.com.cn
[root@shell /scripts]# echo ${url##*.}		#从头开始匹配,最长删除
cn
#从尾删除
[root@shell /scripts]# echo ${url%.*}		#从尾开始匹配,最短删除
www.sina.com
[root@shell /scripts]# echo ${url%%.*}		#从尾开始匹配,最长删除
www
#替换
[root@shell /scripts]# echo ${url/w/W}		#将旧的字符串替换为新的字符串,只替换第一个字符串
Www.sina.com.cn
[root@shell /scripts]# echo ${url//w/W}		#将旧的字符串替换为新的字符串,替换所有
WWW.sina.com.cn
[root@shell /scripts]# echo ${url/w/}		#将第一个匹配到w删除
ww.sina.com.cn
[root@shell /scripts]# echo ${url//w/}		#将所有匹配到w删除
.sina.com.cn

#索引及切片
[root@shell /scripts]# echo $url				#打印变量
w  w  w  .  s  i  n  a  .  com.cn
0  1  2  3  4  5  6  7  8  9
[root@shell /scripts]# echo ${url:0:3}		#从0列开始匹配,切出3列   0-2列
www
[root@shell /scripts]# echo ${url:5:4}		#从5列开始匹配,切出4列, 5-8
ina.
[root@shell /scripts]# echo ${url:5}		#切除前5列=0-4列删除
ina.com.cn

[root@shell /scripts]# cat var-2.sh
#!/bin/bash
#1.定义变量
String='Bigdata process is Hadoop, Hadoop is open source project'
#2.打印变量
echo $String
#3.输出菜单
cat<<EOF
1)打印string长度
2)删除字符串中所有的Hadoop
3)替换第一个Hadoop为Linux
4)替换全部Hadoop为Linux
EOF
#4.提示用户输入对应的数字,执行对应的功能
read -p "请输入上方菜单对应的数字,执行其对应的功能[1|2|3|4]:" Num
#5.根据用户输入的数字进行执行对应的功能
if [ $Num -eq 1 ];then
    echo "正在打印变量String的长度....."
    echo ${
   #String}
elif [ $Num -eq 2 ];then
    echo "正在删除字符串中的所有Hadoop"
    echo ${String//Hadoop/}
elif [ $Num -eq 3 ];then
    echo "正在替换变量中第一个Hadoop为Linux"
    echo ${String/Hadoop/Linux}
elif [ $Num -eq 4  ];then
    echo "正在替换变量中的所有Hadoop为Linux"
    echo ${String//Hadoop/Linux}
else
    echo "你输入的数字不正确!请按照要求输入对应的数字!"
fi
3、变量理论
1、什么是Shell变量?
数据的一种传递方式。  用一个固定的字符串去表示一个不固定的字符串,数值,内容,数据等。

2、Shell变量的好处,便于后续调用

3、Shell变量的命名规则,建议如下:
Hostname_Ip

4、Shell变量定义的方式
4.1. 用户自定义变量,只在当前环境下生效
a=7
a="ni hao"
b='haha o'
Host_ok='good boy'

echo "$a $b $Host_ok"
ni hao haha o good boy

echo ${a}123 $b
ni hao123 haha o

echo $a A $b-B
ni hao A haha o-B

#将命令的执行结果赋值给变量
[root@shell01 ~]# Hostname=$(hostname)
[root@shell01 ~]# echo $Hostname
shell01

# export 可新增,修改或删除环境变量,供后续执行的程序使用。export 的作用时限仅限于此终端该次登陆操作。
export [-fnp] [变量名称]=[变量值]
-f  代表[变量名称]中为函数名称。
-n  删除指定的变量。变量实际上并未删除,只是不会输出到后续指令的执行环境中。
-p  列出所有的shell赋予程序的环境变量,也就是列出本机所有变量,包括自定义变量和系统默认变量
#在命令行定义变量,直接定义和用export定义的区别
[root@shell01 ~]# a=123
[root@shell01 ~]# echo $a
123
[root@shell01 ~]# export -p		#查看本机变量列表,没有刚刚定义的变量a
[root@shell01 ~]# bash
[root@shell01 ~]# echo $a		#执行 bash 后,之前定义的变量a就没有值了

[root@shell01 ~]# export b=234
[root@shell01 ~]# export -p		#查看本机变量列表,刚刚定义的变量b的值在列表中
declare -x b="234"
[root@shell01 ~]# bash
[root@shell01 ~]# echo $b		#执行 bash 后,之前定义的变量b的值还有
234
[root@shell01 ~]# export -n b	#删除定义的变量b
#直接定义的变量不可以在脚本中调用,用export定义的变量可以在脚本中调用
#直接定义和用export定义都将在本终端关闭后失效,也不会在其他终端生效


4.2. 系统环境变量 系统定义好的,主要是定义系统信息的
/etc/profile  /etc/profile.d/*.sh  /etc/bashrc  ~/.bashrc  ~/.bash_profile
[root@shell01 /scripts]# cat var.sh
#!/bin/bash
echo "当前系统登录的用户为:$USER"
echo "当前所在的目录位置为:$PWD"
echo "当前系统的主机名为:$HOSTNAME"
echo "当前系统用户的家目录为:$HOME"
echo "当前系统登录的用户的UID为:$UID"
echo "当前系统登录的终端IP为:$SSH_CONNECTION"
[root@shell01 /scripts]# sh var.sh
当前系统登录的用户为:root
当前所在的目录位置为:/scripts
当前系统的主机名为:shell01
当前系统用户的家目录为:/root
当前系统登录的用户的UID为:0
当前系统登录的终端IP为:10.0.0.1 63017 10.0.0.7 22

4.3. 位置参数变量 变量名是固定的,意思也是固定的,通过脚本进行传递数据
#位置变量: $1  $2 .... $9  ${10} ${11}
4.4. 预定义的变量 脚本中已经定义好的,变量名是固定的,作用也是固定的 $-  $?  $$  $@  $*
[root@shell01 /scripts]# cat path.sh 
#!/bin/bash
echo "当前shell的脚本名为:$0"
echo "当前shell的第一个位置变量为:$1"
echo "当前shell的第二个位置变量为:$2"
echo "当前shell的第三个位置变量为:$3"
echo "当前shell的所有位置变量为:$*"
echo "当前shell的所有位置变量为:$@"
echo "当前shell的位置变量的个数为:$#"
echo "当前shell脚本的PID号为:$$"
echo "上一条命令的执行结果为:$?"

[root@shell01 /scripts]# sh /scripts/path.sh  nginx  php  mysql
当前shell的脚本名为:/scripts/path.sh
当前shell的第一个位置变量为:nginx
当前shell的第二个位置变量为:php
当前shell的第三个位置变量为:mysql
当前shell的所有位置变量为:nginx php mysql
当前shell的所有位置变量为:nginx php mysql
当前shell的位置变量的个数为:3
当前shell脚本的PID号为:8994
上一条命令的执行结果为:0

$* $@ 的区别
$*   把参数作为一个整体字符串返回
$@   把参数一个一个进行返回

[root@shell01 /scripts]# cat test.sh
#!/bin/bash
test() {
   
    echo "未加引号时对比"
    echo $* 
    echo $@
    echo "加入引号之后对比"
    for i in "$*"
    do
        echo $i
    done

    echo "###################"

    for j in "$@"
    do
        echo $j
    done
}
test nginx  php  mysql  ansible

[root@shell01 /scripts]# sh test.sh
未加引号时对比
nginx php mysql ansible
nginx php mysql ansible
加入引号之后对比
nginx php mysql ansible
###################
nginx
php
mysql
ansible
4、变量赋值
read 进行赋值
1. shell脚本中 read 示例语法
[root@shell01 /scripts]# cat read-1.sh
#!/bin/bash
a=11
export b=22
echo $a,$b
read -p "请输入一个值:" Var
echo "你输入的变量值为:$Var "
[root@shell01 /scripts]# sh  read-1.sh
11,22
请输入一个值:oldboy
你输入的变量值为:oldboy

2、测试用户输入的IP地址是否能通
根据用户输入的IP地址进行测试  ping -c1 -W1  10.0.0.2
根据测试的结果,返回给用户,通的就返回通,不通就返回不通
 ping -c1 -W1  10.0.0.2
 -c 发送几个数据包
 -W 几秒内返回数据包有效
 -i 发送每个数据包之间等待的间隔(单位秒)默认设置是等待一秒
 -s 指定要发送的数据字节数。默认56,当与8字节的ICMP头数据组合时,转换为64个ICMP数据字节。
 -I 将源地址设置为指定的接口地址。参数可以是数字IP地址或设备名称。在ping IPv6 linklocal地址时,此选项是必需的。
 -l 如果指定了preload,则ping发送许多不等待回复的数据包。只有超级用户可以选择超过3的预加载
 -q 静默输出。除启动和完成时的摘要行外,不显示任何内容
 -r 绕过正常的路由表并直接发送到连接接口上的主机。如果主机不在直接连接的网络上,则返回错误。如果还是用了-I选项,则此选项可用于通过没有路由的接口ping本地主机。
 -R 记录线路。包含ECHO_REQUEST数据包中的RECORD_ROUTE选项,并在返回的数据包上显示路由缓冲区。请注意,IP报头只能容纳9个这样的路由。许多主机忽略或放弃此选项
 -t ttl 设置IP生存时间值(TTL)
 -v 详细输出

#方法一
#!/bin/bash
#1.提示用户输入一个IP地址
read -p "请输入一个IP地址进行测试连通情况:" Ip
#2.根据用户输入的IP地址进行测试,将测试结果返回给用户
ping -c1 -W1 $Ip  &>/dev/null && echo "该IP地址$Ip 是通畅的!" || echo "该IP地址$Ip 是不通的!"

#方法二
#!/bin/bash
#1.提示用户输入一个IP地址
read -p "请输入一个IP地址进行测试连通情况:" Ip
#2.根据用户输入的IP地址进行测试
ping -c1 -W1 $Ip  &>/dev/null
#3.根据测试结果返回给用户
if [ $? -eq 0 ];then
    echo -e "\033[32m该IP地址 $Ip 是通畅的! \033[0m"
else
    echo -e "\033[31m该IP地址 $Ip 是不通的! \033[0m"
fi

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" 
echo -e "\e[37m 白色字 \e[0m"

echo -e "\033[40;37m 黑底白字 \033[0m"
echo -e "\033[41;37m 红底白字 \033[0m" 
echo -e "\033[42;37m 绿底白字 \033[0m" 
echo -e "\033[43;37m 黄底白字 \033[0m" 
echo -e "\033[44;37m 蓝底白字 \033[0m" 
echo -e &
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值