美文网首页Linux小推车Linux Shell
Linux(十四):Shell 编程

Linux(十四):Shell 编程

作者: 末池桑 | 来源:发表于2019-09-16 11:20 被阅读0次

    一、Hello World 示例

    注:脚本以#!/bin/bash 开头,#!/bin/bash是指此脚本使用/bin/bash来解释执行,#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。

    二、变量

    Shell 编程中变量分为系统变量和用户自定义变量,系统变量就是 OS 内置的变量,比如:HOME、PATH、$USER等,set 命令可以查看当前所有系统变量,而用户自定义变量则是程序员自己定义的变量。

    • 1. 变量定义

    变量定义规则:

    1) 变量名称可以由字母、数字和下划线组成,但是不能以数字开头。
    2) 等号两侧不能有空格
    3) 不能使用标点符号。
    4) 不能使用bash里的关键字(可用help命令查看保留关键字)。
    

    变量使用例子如下图:

    • 2. 将命令返回内容赋值给变量
    1) date=`date` 反引号(Esc下面的按键),将 date 命令的内容赋值给变量 date
    2) date=$(date) 相当于反引号
    
    • 3. 位置参数变量
      执行命令的是否往往可以带上参数,而当我们在执行一个 Shell 脚本也是可以带上参数的,如果希望在脚本里获取到执行脚本时输入的参数信息,就可以使用未知参数变量。比如 : ./localvar.sh 6 7 , 在 localvar.sh 脚本里就可以使用位置参数变量获取到 6 7 这两个参数。位置参数变量详细信息如下:
    $n (功能描述:n 为数字,$0 代表命令本身,$1-$9 代表第一到第九个参数,十以上的参数需要用大括号包含,如${10})
    $* (功能描述:代表命令行中所有的参数,$* 把所有的参数看成一个整体)
    $@ (功能描述:也代表命令行中所有的参数,不过 $@ 把每个参数区分对待)
    $# (功能描述:代表命令行中所有参数的个数)
    

    $* 与 $#区别

    • 4. 预定义变量
      Shell 设计者定义好的变量,与环境变量有点类似,也直接可以在 Shell 脚本中使用,但是不同的是环境变量可以重新定义,而预定义变量是不能让程序员重新定义的。
    $$ (功能描述:当前进程的进程号(PID))
    $! (功能描述:后台运行的最后一个进程的进程号(PID))
    $? (功能描述:最后一次执行的命令的返回状态。如果这个变量的值为 0,证明上一个命令
        正确执行;如果这个变量的值为非 0(具体是哪个数,由命令自己来决定),则证明上一个命令
        执行不正确了。)
    

    四、运算符

    • 1. “((运算式))”或“[运算式]”
    • 2. expr +,-,*,/,% 加、剪、乘(注意要转译)、除、取余

    五、条件判断

    基本语法:[ condition ] (注意 condition 前后要有空格)
    非空返回 true ,可使用 $? 验证(0 为 true,>1 为 false)

      1. 数字比较:
     =    字符串比较
    -lt   小于
    -le   小于等于
    -eq   等于
    -gt   大于
    -ge   大于等于
    -ne   不等于
    
    • 2.字符串比较
    -z 字符串    判断字符串是否为空(为空返回真)
    -n 字符串    判断字符串是否为非空(非空返回真)
    字符串1 == 字符串2    判断字符串1和字符串2是否相等(相等返回真)
    字符串1 != 字符串2    判断字符串1是否和字符串2不相等(不相等返回真)
    
      1. 按照文件权限判断:
    -r 文件    判断该文件是否存在,并且拥有读权限(有读权限为真)
    -w 文件    判断该文件是否存在,并且拥有写权限(有写权限为真)
    -x 文件    判断该文件是否存在,并且拥有执行权限(有执行权限为真)
    -u 文件    判断该文件是否存在,并且拥有SUID权限(有SUID权限为真)
    -g 文件    判断该文件是否存在,并且拥有SGID权限(有SGID权限为真)
    -k 文件    判断该文件是否存在,并且拥有SBit权限(有SBit权限为真)
    
      1. 按照文件类型进行判断
    #常用
    -f 文件    判断该文件是否存在,并且为普通文件(是普通文件为真)
    -e 文件    判断该文件是否存在(存在为真)
    -d 文件    判断该文件是否存在,并且为目录文件(是目录为真)
    #不常用
    -L 文件    判断该文件是否存在,并且为符号链接文件(是符号链接文件为真)
    -p 文件    判断该文件是否存在,并且为管道文件(是管道文件为真)
    -s 文件    判断该文件是否存在,并且为非空(非空为真)
    -S 文件    判断该文件是否存在,并且为套接字文件(是套接字文件为真)
    
      1. 两个文件了之间的比较
    文件1 -nt 文件2    判断文件1的修改时间是否比文件2的新(如果新则为真)
    文件1 -ot 文件2    判断文件1的修改 时间是否比文件2的旧
    文件1 -ef 文件2    判断文件1是否和文件2的Inode号一致,可以理解为两个文件是否为同一个文件。用于判断硬链接是很好的方法。
    
      1. 多重判断
    判断1  -a  判断2    逻辑与,判断1和判断2都成立,最终的结果才为真
    判断1  -o  判断2    逻辑或,判断1和判断2有一个成立,最终的结果就为真
    ! 判断            逻辑非,使原始的判断式取反
    

    六、流程控制

    • 1. if 语句

    语法规则如下:

    if [ 条件判断式 ]
    then
        程序
    elif [ 条件判断式 ]
    then
        程序
    fi
    
    • 2. case 语句

    语法规则如下:

    case $变量名 in
            "值 1")
            如果变量的值等于值 1,则执行程序 1
            ;;
            "值 2")
            如果变量的值等于值 2,则执行程序 2
            ;;
            ...省略其他分支...
            *)
            如果变量的值都不是以上的值,则执行此程序
            ;;
    esac
    
    • 3. for 语句

    语法规则如下:

    -------------for in-------------
    for 变量 in 值 1 值 2 值 3...
    do
        程序
    done
    -------------for(;;)--------------
    for (( 初始值;循环控制条件;变量变化 ))
    do
        程序
    done
    

    * 与@ 区别如下图:

    • 4. while 语句

    语法规则如下:

    while [ 条件判断式 ]
    do
        程序
    done
    

    七、 read 获取控制台输入

    语法规则如下:

    read(参数)(变量)
    参数:
    -p:控制台读取数值时提示文本
    -t:读取输入值的等待时间(秒),没有在指定的时间内输入,则不再等待,往后执行
    变量:
    指定读取值的变量名
    

    八、Shell 脚本函数

    • 1. 系统函数

    系统函数是系统提供给用户使用的函数,basename 与 dirname 就是 Shell 中常用到的函数,其语法规则如下:

    #打印文件名字(除掉路径),指定sufffix后可以把后缀名去掉
    basename [文件路径] [suffix]
    #打印文件所处的绝对路径目录(文件名不打印)
    dirname 文件绝对路径
    
    • 2. 自定义函数
     function funname()
    {
        Action;
        [return int;]
    }
    
    • 无 return 版


    • 带 return 版

    • 函数参数:

    10 不能获取第十个参数,获取第十个参数需要{10}。当 n>=10 时,需要使用 ${n} 来获取参数。
    其他参数如下:

    $#  传递到脚本的参数个数
    $*  以一个单字符串显示所有向脚本传递的参数
    $$  脚本运行的当前进程ID号
    $!  后台运行的最后一个进程的ID号
    $@  与$*相同,但是使用时加引号,并在引号中返回每个参数。
    $-  显示Shell使用的当前选项,与set命令功能相同。
    $?  显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
    

    注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。

    九、MySQL 备份脚本

    以备份本博客的所有数据为例:

    • 1. 写脚本文件,代码如下:
    #!/bin/bash
    #备份路径
    BACK_UP_DIR=/opt/deploy/myblog
    #取当前的时间(作为备份文件的名字)
    DATE_TIME=$(date +%Y%m%d_%H%M%S)
    echo '----------开始备份----------'
    echo "----备份的路径为: $BACK_UP_DIR/$DATE_TIME.tar.gz---------"
    #主机:HOST 用户:USER 密码:PASSWD 数据库:DATABASE
    HOST=localhost
    USER=****
    PASSWD=****
    DATABASE=****
    #创建备份文件路径(不存在则创建)
    [ ! -d $BACK_UP_DIR ] && mkdir -p "$BACK_UP_DIR"
    #执行 mysql 的备份指令
    mysqldump -u${USER} -p${PASSWD} --host=$HOST $DATABASE > $BACK_UP_DIR/$DATE_TIME.sql
    #进入 /opt/deploy目录,打包 upload 和 myblog
    cd /opt/deploy/
    tar -zcvf $DATE_TIME.tar.gz myblog/ upload/
    #备份致 /root/myblogbackup 目录
    mv $DATE_TIME.tar.gz /root/myblogbackup/
    #删除不需要的文件
    rm -rf /opt/deploy/myblog
    #删除一星期以前的文件
    find /root/myblogbackup -mtime +7 -name "*.tar.gz" -exec rm -rf {} \;
    echo "-------------备份文件成功--------------"
    
    • 2. 添加定时任务,每日执行一次脚本
      使用如下命令设置定时任务:
    crontab -e
    #编辑内容如下(每天 0 点备份)
    0 0 * * * /***/***/myblogbackup.sh
    

    注:定时任务设置可参考: Linux(九):定时任务 crontab

    相关文章

      网友评论

        本文标题:Linux(十四):Shell 编程

        本文链接:https://www.haomeiwen.com/subject/qjartctx.html