Shell 编程

1.Shell简介
  • shell的用途

    Linux运维工程师通过shell程序对服务器进行集群管理。

    JavaEE和Python程序员编写Shell脚本对服务器进行维护,比如定时备份数据库

    等等…

  • Shell是什么?

    Shell是一个命令行解释器,它为用户提供了一个Linux内核发送请求以便运行程序的界面系统级程序,用户可以使用Shell来启动,挂起,停止甚至是编写一些程序。

    shell—->内核—->硬件

  • 脚本格式要求

    脚本以#!/bin/bash开头

    脚本需要有可执行权限

  • shell快速入门

    创建一个shell脚本,输出hello world!

    [root@localhost shelltest]# vim hello.sh
    #!/bin/bash
    
    echo "hello world!"
  • 执行方式

    通常使用方式1

    方式1 (输入脚本的绝对路径或者相对路径)

    ​ 首先赋予hello.sh脚本的+x权限

    ​ 执行脚本

    [root@localhost shelltest]# chmod 744 hello.sh
    [root@localhost shelltest]# ./hello.sh
    hello world!
    [root@localhost shelltest]# /root/shelltest/hello.sh
    hello world!

    方式2 (sh+脚本)

    ​ 不赋予脚本+x权限,直接执行

    [root@localhost shelltest]# sh ./hello.sh
    hello world!
2.shell变量
  • 介绍

    分为系统变量和用户自定义变量

    系统变量:$HOME ,$PATH,$USER等

    echo $HOME

    显示shell中所有变量 set

  • 变量的定义

    变量=值

    撤销变量:unset 变量

    声明静态变量 readonly 变量

    例:

    #!/bin/bash
    
    #echo "hello world!"
    A=100
    echo "自定义变量与销毁"
    
    echo "A= $A"
    unset A 
    echo "A="
    
    echo "声明静态变量"
    readonly B=111
    echo "B=$B"
    #unset B #报错,静态变量不能unset
  • 变量定义的规则

    变量名称可以由字母,数字或者下划线组成,不能以数字开头

    变量赋值时等号两侧不能有空格

    变量名称一般习惯为大写

  • 将命令的返回值赋给变量

    ①A= ls -la `反引号 ,运行里面的命令,并把结果返回给变量A

    ②A=$(ls -la ) 等价于反引号

    RESULT=`ls -l /home`
    echo $RESULT
    echo ""
    
    A=$(date)
    echo $A
3.设置环境变量
  • 基本语法

    export 变量名=变量值 (将shell变量输出为环境变量)

    source 配置文件 (让修改后的配置信息立即生效)

    echo $变量名 (查询环境变量的值)

  • 快速入门

    在/etc/profile文件中定义TOMCAT_HOME环境变量

    vim /etc/profile

    #定义一个自己的环境变量
    TOMCAT_HOME=/opt/tomcat/
    export TOMCAT_HOME

    查看环境变量TOMCAT_HOME的值

    [root@localhost shelltest]# source /etc/profile
    [root@localhost shelltest]# echo $TOMCAT_HOME
    /opt/tomcat/

    在另外一个shell程序中使用TOMCAT_HOME

    多行注释 :<<! 注释内容!

    #!/bin/bash
    #使用自定义的环境变量
    echo $TOMCAT_HOME
    [root@localhost shelltest]# ./hello.sh 
    /opt/tomcat/

    注意: 为了让/etc/profile的环境变量生效,需要使用 source /etc/profile

    重启系统或者注销用户

4.位置参数变量
  • 介绍

    当执行一个shell 脚本时,如果希望获取到命令行的参数信息,就可以使用到位置参数变量

    比如 ./myshell.sh 100 200 这个就是一个执行shell的命令行 ,可以在myshell中获取参数信息

  • 基本语法

    $n :n为数字,$0代表命令本身,$1-$9代表第一个参数到第九个参数,十以上的参数需要用大括号包含,{$10}

    $* :这个变量代表命令行中的所有参数,$把所有的参数看成*一个整体**

    $@ : 这个变量也代表命令行中的所有参数,但是$@把每个参数 区分对待

    $# : 这个变量代表命令行中所有参数的个数

  • 实例

    写一个shell脚本,positionPara.sh 在脚本中获取到命令行的各个参数信息

    #!/bin/bash
    #获取各个参数
    echo "命令行参数 0,1,2 $0 $1 $2"
    
    echo "*: $*"
    
    echo " @:$@"
    
    echo "参数个数=$#"
    [root@localhost shelltest]# chmod 744 positionPara.sh 
    [root@localhost shelltest]# ./positionPara.sh  30 60
    
    命令行参数 0,1,2 ./positionPara.sh 30 60
    *: 30 60
     @:30 60
    参数个数=2
5.预定义变量
  • 介绍:

    shell的设计者事先定义好的变量,可以直接在shell脚本中使用

  • 基本语法

    $ $ :当前进程的进程号

    $!:后台运行的最后一个进程的进程号

    $? :最后一次执行的命令的返回状态。如果变量的值为0,证明上一个命令正确执行;如果变量的值为非0(具体是哪个数字,由命令自己决定),则证明上一个命令执行不正确

  • 简单使用预定义变量

    vim prevar.sh

    #!/bin/bash
    echo "当前的进程号=$$"
    
    #后台的方式运行 hello.sh
    
    ./hello.sh & 
    echo "最后的进程号=$!"
    echo "执行的值=$?"
    [root@localhost shelltest]# ./prevar.sh 
    当前的进程号=3068
    最后的进程号=3069
    执行的值=0

Ctrl+c 退出

6.运算符
  • 基本语法

    $((运算式)) 或 $[运算式]

    expr m + n 注意expr 运算符间要有空格

    expr m - n 
    expr \* /,% 乘,除,取余
  • 实例

    计算 (2+3)*4

    #!/bin/bash
    ans1=$(((2+3)*4))
    ans2=$[(2+3)*4]
    
    echo "ans1=$ans1"
    echo "ans2=$ans2"

    请求出命令行的两个参数和

    ans3=$[$1+$2]
    echo "命令行两个参数的和为 $ans3"
    [root@localhost shelltest]# ./test.sh 20 40
    ans1=20
    ans2=20
    命令行两个参数的和为 60
7.条件判断
  • 基本语法

    [ condition ] condition前后要有空格

  • 常用判断条件

    = 字符串比较

    -lt 小于

    -le 小于等于

    -eq 等于

    -gt 大于

    -ge 大于等于

    -ne 不等于

    按照文件权限判断

    ​ - r 有读的权限

    ​ -w 有写的权限

    ​ -x 有执行的权限

    按照文件的类型判断

    ​ -f 文件存在并且是一个常规文件

    ​ -e 文件存在

    ​ -d 文件存在并且是一个目录

  • 案例

    ok是否等于ok

    [root@localhost shelltest]# vim condition.sh
    #!/bin/bash
    
    if [ "ok"="ok" ]
    then
            echo "equal"
    fi
    
    if [ 23 -gt 22 ]
    then
            echo "大于"
    fi
    
    #判断文件是否存在
    if [ -e /root/shelltest/aaa.txt ]
    then
            echo "存在"
    fi
    
    #文件权限
    if [ -r /root/shelltest/aaa.txt ]
    then
            echo "有读的权限" 
    fi
    [root@localhost shelltest]# chmod 744 condition.sh 
    [root@localhost shelltest]# ./condition.sh 
    equal
    大于
    存在
    有读的权限

    删除某个目录下的空文件,并且名字以u开头

    #!/bin/bash
    
    for filename in `find /home/ -name "u*" -type d -empty `
    
    do
    
            echo $filename
            echo `rm -rf $filename`
    
    done
8.流程控制
  • if判断

    if [ 条件判断 ]; then

    ​ 程序

    fi

    或者

    if [ 条件判断 ]

    then

    ​ 程序

    elif [ 条件判断式 ]

    then

    ​ 程序

    fi

  • 案例

    #!/bin/bash
    
    if [ $1 -ge 60 ]
    then
            echo "及格"
    
    elif [ $1 -lt 60 ]
    then
            echo "不及格"
    fi       
    [root@localhost shelltest]# ./testif.sh 78
    及格
  • case语句

    #!/bin/bash
    case $1 in
    "1")
    echo "周一"
    ;;
    
    "2")
    echo "周二"
    ;;
    
    *)
    echo "other"
    ;;
    esac
  • for 循环

    for 变量 in 值1 值2 值3 …

    do

    ​ 程序

    done

    或者

    for ((初始值;循环控制条件;变量变化))

    do

    ​ 程序

    done

    案例:

    #!/bin/bash
    #打印命令行输入的参数
    #使用$*
    
    for i in "$*"
    do
    echo "the num is $i" 
    done
    
    echo "------------"
    #使用 $@
    for j in "$@"
    do
    echo "the num is $j"
    done
    
    [root@localhost ~]# ./printpara.sh 25 23 45
    the num is 25 23 45
    ------------
    the num is 25
    the num is 23
    the num is 45
    #!/bin/bash
    #100以内的整数和
    sum=0
    for ((i=1;i<=100;i++))
    do
    sum=$[$sum+$i]
    done
    echo "100以内的整数和: $sum"
  • while循环

    while [ 条件判断式 ]

    do

    ​ 程序

    done

    案例:

    #!/bin/bash
    
    #从命令行接收参数,输出1---的值
    sum=0
    i=0
    while [ $i -le $1 ]
    do
    sum=$[$sum+$i]
    i=$[$i+1]
    done
    echo "值为: $sum"
9.read读取控制台输入
  • 基本语法

    read [选项] [参数]

    选项:

    -p : 指定读取值时的提示符

    -t :指定读取值时的等待时间(秒),如果在没有指定的时间内输入,就不再等待了。

    参数:

    变量:指定读取值的变量名

  • 实例

    #!/bin/bash
    
    #读取控制台输入的num值
    read -p  "请输入一个数: " NUM1
    echo "第一个值为: $NUM1"
    
    #读取控制台输入的num2值,要求在10s内输入
    read -t 10 -p "请在10秒内输入第二个数: " NUM2
    echo "第二个数为: $NUM2"
10.函数
  • 系统函数

    basename 基本语法

    功能:返回完整路径最后/的部分,常用于获取文件名

    basename [pathname] [suffix]

    basename [string] [suffix] 删除所有前缀,包括最后一个‘/‘,字符,然后将字符串显示出来

    suffix为前缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。

    实例:

    [root@localhost ~]# basename /root/shelltest/aaa.txt 
    aaa.txt
    [root@localhost ~]# basename /root/shelltest/aaa.txt .txt
    aaa

    dirname基本语法

    功能:返回完整路径后/的前面的部分,常用于返回路径部分

    [root@localhost ~]# dirname /root/shelltest/aaa.txt 
    /root/shelltest
  • 自定义函数

    [function] functionname [()]

    {

    ​ Action;

    ​ [return int;]

    }

    调用直接写函数名 functionname [值]

    实例:计算两个参数的和

    #!/bin/bash
    
    function func_sum ()
    {
    
            sum=$[$num1+$num2];
            echo "sum is $sum"
    }
    read -p "请输入第一个数" num1
    read -p "请输入第二个数" num2
    func_sum $num1 $num2
shell编程综合案例

需求:

每天凌晨2点备份数据库admin 到/data/backup/db

备份开始和备份结束能够给出相应的提示信息

备份后的文件要求以备份时间为文件名,并打包成.tar.gz的形式

在备份的同时,检查10天前的备份数据库文件,如果有将其删除


#!/bin/bash
#完成数据库的定时备份

#备份的路径 
BACKUP=/data/backup/db
#当前时间作为文件名
DATETIME=$(date +%Y_%m_%d_%H%M%S)

#echo $DATETIM
echo "=========开始备份========="
echo "备份路径 $BACKUP/$DATETIME.tar.gz"

#主机
HOST=localhost
#用户名
DB_USER=root
#密码
DB_PWD=root
#备份数据库名

DATABASE=test

#创建备份的路径
#如果备份的路径文件夹存在,就使用,否则就创建
[ ! -d "$BACKUP/$DATETIME" ] && mkdir -p "$BACKUP/$DATETIME"

#执行mysql备份数据库的指令
mysqldump -u{$DB_USER} -p{$DB_PWD} $DATABASE | gzip > $BACKUP/$DATETIME/$DATETIME.sql.gz
#打包备份文件
cd $BACKUP
tar -zcvf $DATETIME.tar.gz $DATETIME
#删除临时目录
rm -rf $BACKUP/$DATETIME
#删除十天前的文件

find $BACKUP -mtime +10 -name "*.tar.gz" -exec rm -rf {} \;
echo "=========备份成功========="
[root@izbp1603l3nn58lq8r0ekgz sbin]# crontab -e 
#添加 10 2 * * * /usr/sbin/mysql_db_backup.sh
#保存退出
crontab: installing new crontab

   转载规则


《Shell 编程》 White Spider 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录