Linux之Shell 编程详解(真的超详细哦)

Shell 编程

  • 为什么要学习 Shell 编程 【至少要能看懂代码】
        • Shell 是啥
  • Shell 脚本的执行方式
  • 编写第一个 Shell 脚本
  • 脚本的常用执行方式
  • Shell 的变量
      • Shell 变量介绍
      • shell 变量的定义
      • 定义变量的规则
      • 设置环境变量
      • 多行注释
      • 位置参数变量
          • 基本语法
      • 预定义变量
  • 运算符
  • 条件判断
  • 流程控制
      • if 判断
      • case 语句 (长得很诡异)
      • for 循环
      • while 循环
      • read 读取控制台输入
  • 函数
      • 系统函数
        • basename
        • dirname [和basename正好相反]
      • 自定义函数
  • Shell 编程综合案例

为什么要学习 Shell 编程 【至少要能看懂代码】

  1) Linux 运维工程师在进行服务器集群管理时,需要编写 Shell 程序
     来进行服务器管理。  
  2) 对于 JavaEE 和 Python 程序员来说,工作的需要,会要求
     你编写一些 Shell 脚本进行程序或者是服务器的维 护,比如编写一个
     定时备份数据库的脚本。 
  3) 对于大数据程序员来说,需要编写 Shell 程序来管理集群 

Shell 是啥

  Shell 是一个命令行解释器,用户可以 用 Shell 来启动、挂起、停止甚至
  是编写一些程序。

Shell 脚本的执行方式

   脚本格式要求 
   1) 脚本以#!/bin/bash 开头 
   2) 脚本需要有可执行权限 

编写第一个 Shell 脚本

  需求说明:创建一个 Shell 脚本,输出 hello world! 
   先建一个目录shell来放脚本
       vim hello.sh  【脚本后缀是sh】      
   进入脚本文件后
      #!/bin/bash   【必须要这句话】
      echo "hello,world~"
      【写完之后是没有权限执行的】

脚本的常用执行方式

  1.要想执行,就加权限
      chmod u+x hello.sh
     再执行
      ./hello.sh 或者使用绝对路径 /root/shcode/hello.sh
  2.不加权限,直接输sh hello.sh也可

Linux之Shell 编程详解(真的超详细哦)_第1张图片

请添加图片描述

Shell 的变量

Shell 变量介绍

   1) Linux Shell 中的变量分为,系统变量和用户自定义变量。 
   2) 系统变量:$HOME、$PWD、$SHELL、$USER 等等,比如: 
      echo $HOME 等等.. 
   3) 显示当前 shell 中所有变量:set 

shell 变量的定义

   1) 定义变量:变量名=值 
   2) 撤销变量:unset 变量 
   3) 声明静态变量:readonly 变量,注意:不能 unset 
   比如:
     1:定义变量 A 
         A=100
        输出A=100
         echo A=$A或echo "A=$A"
     2) 撤销变量 A 
         unset A
     3) 声明静态的变量【不会反复定义和初始化】 B=2,不能 unset
         readonly B=2
         【撤销不了,输unset也没用】
     4) 可把变量提升为全局环境变量,可供其他 shell 程序使用

定义变量的规则

    1) 变量名称可以由字母、数字和下划线组成,但是不能以数字开头。
        比如5A=200就不对 
    2) 等号两侧不能有空格 
       只能写A=100   不能写A = 100
    3) 变量名称一般习惯为大写, 这是一个规范【小写也能运行】
  将命令的返回值赋给变量 【以输出日期为例】
    1) A=`date`反引号,运行里面的命令,并把结果返回给变量 A 
    2) A=$(date) 等价于反引号 
    【如果写A=date,表示把单词赋值给A】

设置环境变量

  1) export 变量名=变量值 
    (功能描述:将 shell 变量输出为环境变量/全局变量) 
  2) source 配置文件 (功能描述:让修改后的配置信息立即生效) 
  3) echo $变量名 (功能描述:查询环境变量的值) 
  比如:
    1)在/etc/profile 文件中定义 AMIAO 环境变量
       先进入/etc/profile,在最下面增加一行
           export AMIAO=/opt/myamiao
       然后保存,再刷新
           source /etc/profile           
    2) 查看环境变量AMIAO 的值 
       输 each AMIAO 就能得到值了
    3) 在另外一个 shell 程序中使用 AMIAO 

多行注释

      :<

位置参数变量

   当我们执行一个 shell 脚本时,如果希望获取到命令行的参数信息,就
   可以使用到位置参数变量 
   比如 : 
      ./myshell.sh 100 200 
      这个就是一个执行 shell 的命令行,可以在 myshell 脚本中获
      取到参数信息 
基本语法
   $n 
     n 为数字,$0 代表命令本身,$1-$9 代表第一到第九个参数,
     十以上的参数要用大括号包含,如${10}
   $* 
     这个变量代表命令行中所有的参数,【把所有的参数看成一个整体】  
   $@
     这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待
   $#
     功能描述:这个变量代表命令行中所有参数的个数 
   
 比如:
  编写一个 shell 脚本 amiao.sh 在脚本中获取到命令行的各个参数信息。

Linux之Shell 编程详解(真的超详细哦)_第2张图片

Linux之Shell 编程详解(真的超详细哦)_第3张图片

预定义变量

  就是 shell 设计者事先已经定义好的变量,可以直接在 shell 脚本中使用 
  1) $$   获取当前进程的进程号(PID) 
  2) $!   获取后台运行的最后一个进程的进程号(PID) 
  3) $?   查上一次命令是成功了还是失败了
     如果这个变量的值为 0,证明上一个命令正确执行;如果这个变 量的值
     为非 0则证明上一个命令执行不正确了。

Linux之Shell 编程详解(真的超详细哦)_第4张图片

运算符

  1) “$((运算式))”或“$[运算式]”或者
      expr m + n //expression 表达式 
  2) 注意 expr 运算符间要有空格, 如果希望将 expr 的结果赋给某个
     变量,使用 `` 
  3) expr m - n 
  4) expr \*, /, % 乘,除,取余 
  比如:
    在shell中建一个oper.sh 
  1:计算(2+3)X4 的值
    1)R1=$(((2+3)*4)) 
      echo "r1=$R1" 
    2) R2=$[(2+3)*4] 
      echo "r2=$R2" 
    3) expr T=`expr 2 + 3` 
       R4=`expr $T \* 4` 
       echo "r4=$R4"
  2:请求出命令行的两个参数[整数]的和 20 50 
     SUM=$[$1+$2] 
     echo "sum=$SUM"
     [利用了位置变量]
     退出去输 sh oper.sh 20 50 就能得到结果

条件判断

 判断语句:[ condition ](注意 condition 前后要有空格) 
   非空返回 true,可使用$?验证(0 为 true,>1 为 false) 
  比如: 
    输[ hspEdu ] 返回 true,输 [ ] 返回 false         
    [ condition ] && echo OK || echo notok 
         表示条件满足,执行后面的语句 
 常用判断条件 
    1) = 字符串比较 
    2) 两个整数的比较 
      -lt 小于 
      -le 小于等于 
      -eq 等于 
      -gt 大于 
      -ge 大于等于 
      -ne 不等于
    3) 按照文件权限进行判断 
      -r 有读的权限
      -w 有写的权限 
      -x 有执行的权限
    4) 按照文件类型进行判断 
      -f 文件存在并且是一个常规的文件 
      -e 文件存在 
      -d 文件存在并是一个目录
    比如;
    1:"ok"是否等于"ok"    使用 = 
    2:23 是否大于等于 22    使用 -ge 
    3:/root/shcode/aaa.txt 目录中的文件是否存在  使用 -f
    [如果这些语句判断出来都是"否定",就啥也不会输出]

Linux之Shell 编程详解(真的超详细哦)_第5张图片

流程控制

if 判断

  多分支
  if [ 条件判断式1 ] 
  then
  代码1
  elif [条件判断式2] 
  then 
  代码2
  fi 
 !!!注意:[ 条件判断式 ],中括号和条件判断式之间必须有空格 
  比如:
    请编写一个 shell 程序,如果输入的参数,大于等于 60,则输出 "及格
    了",如果小于 60,则输出 "不及格" 

Linux之Shell 编程详解(真的超详细哦)_第6张图片

case 语句 (长得很诡异)

   case $变量名 in 
   "值 1") 
           如果变量的值等于值 1,则执行程序 1
   ;;
           表示结束第一个语句
   "值 2") 
           如果变量的值等于值 2,则执行程序 2 
   ;;
           …省略其他分支…
   *)
           如果变量的值都不是以上的值,则执行此程序 
   ;;
   esac
           表示结束整个程序[把case反着写]
       
   比如:
    testCase.sh     
      1 :当命令行参数是 1 时,输出 "周一", 是 2 时,就输出"周二",
      其它情况输出 "other"

Linux之Shell 编程详解(真的超详细哦)_第7张图片

for 循环

  1.for 变量 in 值 1 值 2 值 3… 
    do
    程序/代码 
    done 
    
   比如:
    testFor1.sh 
    打印命令行输入的参数 [这里可以看出$* 和 $@ 的区别]

Linux之Shell 编程详解(真的超详细哦)_第8张图片

Linux之Shell 编程详解(真的超详细哦)_第9张图片

  2.for (( 初始值;循环控制条件;变量变化 ))      
    do
    程序/代码 
    done 
  比如:
    testFor2.sh 
    从 1 加到 100 的值输出显示

Linux之Shell 编程详解(真的超详细哦)_第10张图片

    如果把100变成变量,可以求1到任意值的和

Linux之Shell 编程详解(真的超详细哦)_第11张图片

while 循环

  1.while [ 条件判断式 ]
    do
    程序 /代码 
    done 
    注意:while 和 [有空格,条件判断式和 [也有空格 
   比如:
     从命令行输入一个数 n,统计从 1+..+ n 的值是多少?
    SUM=0     #初始化
    i=0 
    while [ $i -le $1 ]     #i<=传进来的值
    do 
         SUM=$[$SUM+$i] 
         i=$[$i+1]          #i 自增,不能写i++
    done 
    echo "执行结果=$SUM" 

read 读取控制台输入

    read(选项)(参数) 
    选项: 
      -p:指定读取值时的提示符; 
      -t:指定读取值时等待的时间(秒),
          如果没有在指定的时间内输入,就不再等待了。。 
    参数变量:指定读取值的变量名
   比如:
    1.读取控制台输入一个 NUM1 值 
      read -p "请输入一个数 NUM1=" NUM1 
      echo "你输入的 NUM1=$NUM1"  
      [如果一直不输值,程序就会一直卡在那里]
    
    2:读取控制台输入一个 NUM2 值,在 10 秒内输入。
      read -t 10 -p "请输入一个数 NUM2=" NUM2 
      echo "你输入的 NUM2=$NUM2"

函数

  shell 编程和其它编程语言一样,有系统函数,也可以自定义函数。

系统函数

basename

       用于返回完整路径最后 / 的部分,常用于获取文件名 
     basename [pathname] [suffix] 
     basename [string] [suffix] 
     [basename 命令会删掉所有的前缀包括最后一个(‘/’)字符,
     然后将字符串 显示出来。] 
    选项: suffix 为后缀,如果 suffix 被指定了,basename 会将
    pathname 或 string 中的 suffix 去掉。
    比如:
       请返回 /home/aaa/test.txt 的 "test.txt" 部分 
          basename /home/aaa/test.txt
         如果输basename /home/aaa/test.txt .txt
           就返回test

dirname [和basename正好相反]

      用于返回完整路径最后 / 的前面的部分,常用于返回路径部分 
      dirname 文件绝对路径 (从给定的包含绝对路径的文件名中去除文件
      名(非目录的部分),然后返回剩下的路径(目录的部分)) 
     比如:
        请返回 /home/aaa/test.txt 的 /home/aaa 
           dirname /home/aaa/test.txt 

自定义函数

   [ function ] funname[()] 
   { 
         Action; 
         [return int;]
    }
    调用直接写函数名:
    funname [值] 
    
    比如:
    1:计算输入两个参数的和(动态的获取), 函数名: getSum
         function getSum() { 
             SUM=$[$n1+$n2]     #n1和n2是手动输入的数
             echo "和是=$SUM" 
         }
         read -p "请输入一个数 n1=" n1   #输入两个值 
         read -p "请输入一个数 n2=" n2 
         getSum $n1 $n2                #调用自定义函数 

Shell 编程综合案例

   1) 每天凌晨 2:30 备份 数据库 hspedu 到 /home/date
   2) 备份开始和备份结束能够给出相应的提示信息 
   3) 备份后的文件要求以备份时间为文件名,并打包成 .tar.gz 的形式
      比如:2021-03-12_230201.tar.gz 
   4) 在备份的同时,检查是否有 10 天前备份的数据库文件,
      如果有就将其删除。 
   5) 画一个思路分析图

Linux之Shell 编程详解(真的超详细哦)_第12张图片

 代码 
 /usr/sbin/mysql_db.backup.sh 
 #备份目录
 BACKUP=/data/backup/db 
 #当前时间 
 DATETIME=$(date +%Y-%m-%d_%H%M%S) 
 echo $DATETIME
 #数据库的地址 
 HOST=localhost 
 #数据库用户名 
 DB_USER=root 
 #数据库密码 
 DB_PW=hspedu100 
 #备份的数据库名 
 DATABASE=hspedu 
 #创建备份目录, 如果不存在,就创建 
 [ ! -d "${BACKUP}/${DATETIME}" ] && mkdir -p "${BACKUP}/${DATETIME}"
 #备份数据库
 mysqldump -u${DB_USER} -p${DB_PW} --host=${HOST} -q -R --databases ${DATABASE} | gzip > ${BACKUP}/${DATETIME}/$DATETIME.sql.gz 
 #将文件处理成 tar.gz 
 cd ${BACKUP} 
 tar -zcvf $DATETIME.tar.gz ${DATETIME} 
 #删除对应的备份目录 
 rm -rf ${BACKUP}/${DATETIME} 
 #删除 10 天前的备份文件 
 find ${BACKUP} -atime +10 -name "*.tar.gz" -exec rm -rf {} \; 
 echo "备份数据库${DATABASE} 成功~"

你可能感兴趣的:(linux的各种编程,linux,运维,unix,1024程序员节)