01-shell的基本概述与变量的定义

 Shell的基本概述

shell是一个命令解释器,它在操作系统的最外层,负责连接与用户进行对话,将用户输入的命令翻译给操作系
统,并将处理结果输出至屏幕
 
shell命令是存在交互式、和非交互式的两种方式
 
什么是shell???
1)将系统命令堆积在一起,顺序执行(简称:系统命令堆积)
2)特定的格式+特定的语法+系统命令=文件
 
Shell能做什么(shell其实就是基于标准化之上的-->脚本工具)
1)基础配置:系统初始化操作,系统更新,内核调整,网络,时区,ssh优化
2)安装服务:LNMP,LAMP,MySQL,nginx,redis,
3)配置变更:nginx conf,PHP conf,MySQL conf,redis conf
4)业务部署:shell配合git、jenkins、实现自动化部署,php、java、代码,以及代码回滚
5)日常备份:使用shell脚本对mysql进行每晚的全备与增量备份
6)信息采集:zallix+shell,硬件,系统,服务,网络,等等
7)日志分析:取值-->排序-->去重-->统计-->分析
8)服务扩容:扩容:监控服务器集群cpu,如cpu负载持续80% + 触发动作(脚本),脚本:调用api开通云主机,
   -->初始化环境-->加入集群-->对外提供
9)服务缩容:监控服务器集群cpu使用率,-->低于20%-->检测当前有多少web节点,-->判断是否超过预设-->缩
   减对应的预设状态-->变更负载的配置
注意:shell脚本主要的作用是简化操作步骤,提高效率,减少人为干预,减少系统故障
 
学习shell脚本需要哪些预备知识,如何才能学好shell脚本
1)熟悉使用vim编辑器
2)熟练使用linux
3)熟练使用linux三剑客
注意:如果我们对命令使用不熟练,对基本服务也不会手动搭建,那么一定学不会shell
那么我们究竟如何才能学好shell脚本,基础命令+基础服务+经常练习+思路!!!
 
Shell的基本规范
1)脚本存放固定目录/scripts
2)开头加!/bin/bash     作用:告诉我脚本使用哪种命令解析器,如不指定shell,默认以bash执行
   #!/usr/bin/bash
   1. 脚本如果以./方式执行,需要拥有执行权限
   2. 直接使用解析器命令执行脚本时,不需要执行权限也可以执行脚本
3)附带作者及版权信息
   Auther:chenyun
4)脚本扩展名用.sh
   check_nginx.sh
5)脚本中尽量不要用中文
6)成对的符号一次书写完成
7)循环格式一次性输入完成
 
Shell的脚本变量
1)shell变量概述
2)shell变量赋值
3)shell变量替换
4)shell变量运算
5)shell变量案例
 
什么是变量?
变量是一个传递数据的一种方法,简单理解,就是用一个固定的字符串去表示不固定的值,便于后续引用
 
变量命名规范
变量定义时名称要求:字母、数字、下划线几个组成,尽量用字母开头,{变量名最好具备一定的含义,但不要与系统命令冲突}
如 Hostname_ip=$(hostname -i),
等号是赋值,需要注意:等号两边不能有空格,其次定义的变量不要与系统命令相冲突
 
Shell变量定义的方式
1)用户自定义变量:人为定义变量名称
2)系统环境变量:保存的是和系统环境相关的数据
3)位置参数变量:向脚本中进行参数传参,变量名不能自定义,变量作用是固定的
4)预定义的变量:是bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的
 
Shell变量定义实践
1. 用户定义变量示例,当前shell有效
  1)定义变量,变量名=变量值中不能出现“-”横杠命名
  [root@shell ~]# var="hello world"   定义变量有空格时一定要有用""号,让它们输出时是一个整体
  
  2)引用变量,$变量 或 ${变量}
  [root@shell ~]# echo $var_log       $var_log当做一个整体
  [root@shell ~]# echo ${var}_log     ${var}_log var变量加后缀_log
  
  3)查看变量,set显示所有变量,包括自定义变量和环境变量
  [root@shell ~]# set | grep var    查看自定义变量
  [root@shell ~]#echo $PATH        查看环境变量
  
  4)取消变量,只在当前shell中生效
  unset var
  
  5)注意事项,引用变量时注意事项,""双引号属于弱引用,''单引号属于强引用
  a 在定义变量的时候,比如:var="$(var)"
  b 在引用变量的时候,尽可能的使用双引号   echo "$var"
  c 在我们使用echo输出的时候,如果输出的字符串中有特殊的符号,建议使用单引号  echo '#$123'
  
  echo "$var is good is \$500"
  $var被解析
  $500前使用\转译符,这里$500不被解析
  -------------------------------------------------------------------
  1. 如何定义变量
  2. 变量的命名规范,不要与系统命令冲突,不要太随意
  3. 使用变量需要注意$var_log 以及"" '' 带来的问题
  
2. 系统环境变量示例,在当前shell和子shell都有效
  1)定义环境变量,export变量,将自定义变量转换成环境变量
     [root@shell ~]# export JAVA_HOME=/usr/local/jdk   将变量转为环境变量
     [root@shell ~]# echo $JAVA_HOME
      /usr/local/jdk
  2)使用已定义好的系统变量
     [root@shell ~]# echo $SSH_CLIENT   使用系统已定义好变量
     10.0.0.1 49741 22
     echo $HOME:打印用户当前家目录
     echo $HOMENAME:打印主机名
     echo $PWD:打印当前所在路径
     echo $SSH_CONNECTION:打印当前连接服务器使用的地址和端口
    
3. 预先定义变量参数示例,系统内置变量的使用方法。需要注意:$*和$@的区别
echo $0:当前shell脚本的文件名  
echo $1:第一个shell脚本位置参数
echo $2:第二个shell脚本位置参数
echo $3:第三个shell脚本位置参数
echo $*:所有传递的位置参数
echo $@:所有传递的位置参数
echo $#:总共传递的参数个数
echo $$:当前程序运行的PID
echp $?:上一个命令执行的返回结果
 
    $*和$#的区别
    $*和$@在没有加引号时,两者都是返回传入的参数,但加了引号后
    $*把参数作为一个字符串整体(单字符串)返回
    $@把每个参数作为一个一个字符串返回
    ----------------------------------------------------------
    
   位置参数是什么?在执行脚本的时候,在脚本后面写入内容,按空格分隔
   [root@shell ~]# /etc/init.d/network start  #start就算第一个位置参数
 
4. 补充:将命令执行结果传递给变量(命令替换)
   # 根据系统时间打印明年时间
   echo $(date +%Y -d +"1year") 或
   echo $(($(date +%Y)+1))
   2021
   
   # 打包/root下面所有的.txt的文件
   [root@shell ~]# tar -zcf /root/data.tar.gz $(find /root -type f -name "*.txt")
   [root@shell ~]# tar -tf data.tar.gz
    ./3.txt
    ./4.txt
    
Shell的变量赋值
1. read示例语法
#!/bin/bash
  read -p "请输入你要备份的目录:" file
  cd /
  tar -zcf backup.tar.gz .$file
  echo ".......... backup $file ................"
  echo ".......... backup $file end ............"
 
  [root@shell scripts]# /bin/bash read.sh
  请输入你要备份的目录:/tmp
  ............ backup /tmp .....................
  ............. backup /tmp end .................
  [root@shell scripts]# tar -tf backup.tar.gz
  tmp/
  tmp/.X11-unix/
  
  示例2:
  编写一个测试用户IP能否拼通的脚本
  要求:拼通返回IP正常拼通,不通返回IP无法正常拼通
  
  思路:第一,执行时提示输入IP   read -p
            第二,让IP只拼一次          ping -c1
            第三,指定超时时间          ping -W1
            第四,返回命令执行结果   echo $?
-----------------------------------------------
[root@shell scripts]#vim /scripts/ping.sh
  #!/bin/bash
  read -p "请您输入测试IP:" IP
  ping -W1 -c1 $IP >/dev/null
  rc=$?
  
  if [ $rc == 0 ];then
         echo "IP可以正常拼通"
          else
         echo "IP无法拼通"
  fi
 
  [root@shell scripts]# /bin/bash ping.sh
  请您输入测试IP:10.0.0.1
  IP可以正常拼通
  [root@shell scripts]# /bin/bash ping.sh
  请您输入测试IP:10.0.0.2
  IP无法拼通
  
  示例3:
  使用read命令写一个脚本修改主机名和IP地址
  思路:1. 提示用户输入修改主机名称或IP
            2. 提示用户是否确认此操作
            3. 真的执行修改
  #!/bin/bash
  #1. 提示用户输入要修改的主机名称,然后打印主机名称
  read -p "请输入您想要修改的主机名称" HostName
  echo "您要修改的主机名称为$HostName"
  
  #2. 询问用户是否确认修改,如果确认执行shell,否则退出
  read -p "您确认要修改如下主机名称[y|n]" rc
  
  #3. 判断用户输入是y还n
  if [ $rc == y ];then
          hostnamectl set-hostname $HostName
  else
          exit
  fi
   
Shell变量替换
$(变量#匹配规则)         从头开始匹配,最短删除
$(变量##匹配规则)       从头开始匹配,最长删除
$(变量%匹配规则)        从尾开始匹配,最短删除
$(变量%%匹配规则)     从尾开始匹配,最长删除
$(变量/旧字符串/新字符串)    替换变量内的旧字符串为新字符串,只替换一个
$(变量//旧字符串/新字符串)    替换变量内的旧字符串为新字符串,全部替换
 
  1)从尾往前删除变量内容
  最短删除
  [root@shell scripts]# url=www.sina.com.cn
  [root@shell scripts]# echo ${url%.*}
  
  最长删除
  [root@shell scripts]# echo ${url%%.*}
  www
  
  2)从前往尾删除变量内容
  最短删除
  [root@shell scripts]# echo ${url#*.}
  
  最长删除
  [root@shell scripts]# echo ${url##*.}
  cn
  
  [root@shell scripts]# free=$(free -m|grep ^M|awk '{print $3/$2*100}')
  [root@shell scripts]# echo $free
  12.1399
  [root@shell scripts]# echo ${free%.*}
  12
  
  3)变量内容替换
  [root@shell scripts]# echo $url
  [root@shell scripts]# echo ${url/n/N}        只替换一个
  [root@shell scripts]# echo ${url//n/N}      全部替换
  
  应用场景
  1. 查看内存/当前使用状态,如果使用率超过80%,则发送报警邮件
  2. 场景实践,在/backup下创建10个.txt的文件,找到/backup目录下所后缀名为.txt的文件
    1)批量修改txt为txt.bak
    2)把所有的.bak文件打包压缩为123.tar.gz
    3)批量还原文件的名字,及把增加的.bak再删除
  3. 使用shell脚本打印、系统版本、内核版本平台、虚拟平台、静态化平台、eth0网卡IP地址、lo网卡IP地址
     当前外网IP地址
  4. 需求描述:变量string="Bigdata process is Hadoop,Hadoop is open source project",执行脚本后,
     打印输出string字符串变量,并给用户以下选项
        1)打印string长度
        2)删除字符串中所有的Hadoop
        3)替换第一个Hadoop为Linux
        4)替换全部Hadoop为Linux
        用户输入数字1|2|3|4,可以执行对应项的功能,输入q|Q则退出交互模式
    
问答题:
1. 用shell或者python编写一个脚本,要求如下
  在每个月第一天备份并压缩/etc/目录下所有内容,存放在/root/bak目录里,文件名为如下形式yymmd_etc,yy为年,mm为月,脚本名称为filebck存放在root 目录下
  思路:
  1. 备份什么?                  源    /etc
  2. 备份到哪?                 目标 /root/bak
  3. 使用什么方式备份       压缩 tar
  3. 备份的周期?              每月第一天,如何每月第一天,crond
--------------------------------------------------------------------
[root@shell scripts]# vim /scripts/fileback.sh
  #/bin/bash
  ####################################################
  # 脚本要求:                                        # 
  #   1)每个月第一天备份并压缩/etc/目录下所有内容      #
  #   2)存放在/root/bak目录里                        #
  #   3)文件名为如下形式yymmd_etc                    #
  #   4)脚本名称为filebck存放在root目录下             #
  ###################################################
  
  DestPath=/root/bak
  Date=$(date +%Y_%m_%d)
  
  # 1. 准备目标位置
  [ ! -d $DestPath ] && mkdir -p $DestPath
  
  # 2. 备份到目标位置
  cd /
  tar -zchf $DestPath/${Date}_etc.tar.gz ./etc  
  [root@shell scripts]# crontab -e
  0 1 1 * * /bin/bash /scripts/fileback.sh &>/dev/null
 
2. 场景实践,查看内存/当前使用状态,如果使用率超过80%,则发送报警邮件
  1)如何查看内存            free -m
  2)如何查看内存百分比        使用的内存 / 总的内存 *100=使用百分比
     free -m|awk '/Mem/ {print $3/$2*100}'
    
  [root@shell ~]# vim /scripts/free_use.sh
  #!/bin/bash
  ##################################
  #         查看内存使用率          #
  ##################################
  
  free_use=$(free -m|awk '/Mem/ {print $3/$2*100}')
  
  if [ ${free_use%.*} -gt 80 ];then
          echo "你的内存使用率超过了80%,当前内存使用率是${free_us}%"
  else
          echo "当前内存使用率是${free_use}%"
  fi
 
3.  场景实践,在/backup下创建10个.txt的文件,找到/backup目录下所后缀名为.txt的文件
  1)批量修改txt为txt.bak
  2)把所有的.bak文件打包压缩为123.tar.gz
  3)批量还原文件的名字,及把增加的.bak再删除
rename    txt            txt.bak          *.txt
             要修改的类型    修改成什么类型    操作的对象
 
方法一:rename重命名
[root@shell scripts]# vim rename.sh
#!/bin/bash
#批量修改文件名
 
#定义变量
T=txt
B=bak
 
#把/backup目录下的.txt结尾的文件修改为.txt.bak
cd /backup && rename $T $T\.$B *.txt
 
#打包
tar zcf /backup/123.tar.gz $(find /backup/ -type f -iname "*.bak")
 
#还原
rename $T\.$B $T *
 
方法二:sed重命名
[root@shell scripts]# vim /scripts/sed_name.sh
#!/bin/bash
#批量修改文件名
 
#1. 将文件批量重命名
find /backup/ -type f -iname "*.txt"|sed -r 's#(.*)#mv \1 \1.bak#g'|bash
 
#2. 打包
tar -zcf /backup/123.tar.gz $(find /backup/ -type f -iname "*.bak")
 
#3. 还原
find /backup/ -type f -iname "*.bak"|sed -r 's#(.*).bak#mv \1.bak \1#g'|bash
 
方法三:使用变量替换
[root@shell scripts]# vim /scripts/for_name.sh
#!/bin/bash
###########################
#      批量修改文件名     #
###########################
 
File_txt=$(find /backup/ -type f -iname "*.txt"|xargs >/backup/txt.tt)
for i in $(cat /backup/txt.tt)
do
    mv $i $i.bak
done
 
tar czf /backup/123.tar.gz ./*.bak
 
File_bak=$(find /backup/ -type f -iname "*.bak" >/backup/tar.tt)
for j in $(cat /backup/tar.tt)
do
    mv $j ${j%.*}
done
 
Shell变量运算
1)整数运算,expr    $(())   $[] ,不支持小数运算
+       加
-        减
*        乘
/        除
%      余     
[root@shell backup]# expr $num + $num1   
30
[root@shell backup]# expr $num - $num1 
-10
[root@shell backup]# expr $num \* $num1
200
[root@shell backup]# expr $num / $num1        
0
[root@shell backup]# expr $num % $num1
10
[root@shell backup]# echo $(( num + num1 ))
[root@shell backup]# echo $[ num + num1 ]
 
2)小数运算bc,用的不是很多,了解即可
[root@shell backup]# yum -y install bc
[root@shell backup]# echo 2 \* 4|bc
8
[root@shell backup]# echo 7 % 4|bc
3
[root@shell backup]# echo "scale=2;7 / 4"|bc
1.75
[root@shell backup]# awk 'BEGIN{print 1/2}'
0.5
 
Shell变量案例
1)使用shell脚本打印,系统版本、内核版本平台、虚拟平台、静态主机名、ens33网卡、IP地址、lo网卡IP
[root@shell scripts]# vim system.sh
#!/bin/bash
System=$(hostnamectl | grep System|awk '{print $3,$4,$5}')
Kernel=$(hostnamectl | grep Kernel|awk '{print $2,$3}')
Vt=$(hostnamectl | grep Virtualization|awk '{print $2}')
Statichostname=$(hostnamectl | grep "Static hostname"|awk '{print $3}')
Ens33=$(ifconfig ens33|awk 'NR==2{print $2}')
Lo=$(ifconfig lo|awk 'NR==2{print $2}')
 
echo "当前系统版本是:$System"
echo "当前系统内核版本是:$Kernel"
echo "当前虚拟平台是:$Vt"
echo "当前静态主机名是:$Statichostname"
echo "当前ens33网卡IP是:$Ens33"
echo "当前lo网卡IP是:$Lo"
[root@shell scripts]# sh +x /scripts/system.sh
当前系统版本是:CentOS Linux 7
当前系统内核版本是:Linux 3.10.0-1062.el7.x86_64
当前虚拟平台是:vmware
当前静态主机名是:shell
当前ens33网卡IP是:172.16.1.100
当前lo网卡IP是:127.0.0.1
 
2)需求描述:变量string="Bigdata process is Hadoop, Hadoop is open source project",执行脚本后,打印输出string字符串变量,并给出用户以下选项:
  1. 打印string长度
[root@shell ~]# echo $string | wc -c
[root@shell ~]# echo ${#string}
  1. 删除字符串中所有的Hadoop
[root@shell ~]# echo ${string//Hadoop/}
Bigdata process is , is open source project
  1. 替换第一个Hadoop为Linux
echo ${string/Hadoop/Linux}
Bigdata process is Linux, Hadoop is open source project
  1. 替换全部Hadoop为Linux
[root@shell ~]# echo ${string//Hadoop/Linux}
Bigdata process is Linux, Linux is open source project
用户输入数字1| 2| 3| 4|,可以执行对应项的功能,输入q|Q则退出交互模式
 
[root@shell scripts]# vim string.sh
#!/bin/bash
#打印字符串,并列出操作选项,执行对应操作
 
string="Bigdata process is Hadoop, Hadoop is open source project"
echo $string
cat <<EOF
1. 打印string长度
2. 删除字符串中所有的Hadoop
3. 替换第一个Hadoop为Linux
4. 替换全部Hadoop为Linux
EOF
read -p "输入数字1| 2| 3| 4|,或输入q|Q则退出交互模式:" var
 
if [ $var -eq 1 ];then
   echo "当前string字符长度是:${#string}"
fi
 
if [ $var -eq 2 ];then
   echo ${string//Hadoop/}
fi
 
if [ $var -eq 3 ];then
   echo ${string/Hadoop/Linux}
fi
 
if [ $var -eq 4 ];then
   echo ${string//Hadoop/Linux}
fi
 
if [ $var == q ];then
   exit
fi
 
 

 

posted @ 2020-05-12 22:20  向云而生(陈云)  阅读(323)  评论(0编辑  收藏  举报