• shell脚本的系统性学习笔记


    shell脚本的系统性学习笔记

    一、入门基础

    1.1 脚本的书写格式

    ​ 脚本文件第一行要求使用shebang(#!)符号指定一个脚本的解释器,如#! /bin/bash、#! /bin/sh、#!/usr/bin/env python等

    <<符号后面的关键词可以是任意字符串,但前面使用什么关键词,结束注释时必须使用相同的关键词。如果从<<ABC开始注释,则结束注释信息时也必须使用ABC(字母区分大小写)。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cupkwE7P-1660468289831)(C:\Users\liwei\AppData\Roaming\Typora\typora-user-images\image-20220814152816041.png)]

    1.2脚本的各种执行方式

    1)脚本文件自身没有可执行权限

    如果暂时还没有给脚本文件可执行的权限,那么默认脚本是无法直接执行的,但bash或sh这样的解释器,可以将脚本文件作为参数(读取脚本文件中的内容)来执行脚本文件。

    2)脚本文件具有可执行权限

    脚本文件一旦有了执行权限,就可以使用绝对路径或相对路径执行了。

    3)开启子进程执行的方式 bash 绝对路径、相对路径执行 默认开启

    4)不开启子进程的执行方式

    使用source或.(点)命令来执行脚本文件。

    1.3数据的输入与输出

    echo 、printf

    1.4输入输出重定向

    标准输出的文件描述符为1,标准错误输出的文件描述符为2。而标准输入的文件描述符则为0。

    如果希望改变输出信息的方向,可以使用>或>>符号将输出信息重定向到文件中。使用1>或1>>可以将标准输出信息重定向到文件(1可以忽略不写,默认值就是1),也可以使用2>或2>>将错误的输出信息重定向到文件。这里使用>符号将输出信息重定向到文件,如果文件不存在,则系统会自动创建该文件,如果文件已经存在,则系统会将该文件的所有内容覆盖(原有数据会丢失!)。而使用>>符号将输出信息重定向到文件,如果文件不存在,则系统会自动创建该文件,如果文件已经存在,则系统会将输出的信息追加到该文件原有信息的末尾。

    Linux系统中有一个特殊的设备/dev/null,这是一个黑洞。无论往该文件中写入多少数据,都会被系统吞噬、丢弃。

    1.5变量

    当需要读取变量值时,需要在变量名前添加一个美元符号“$”;而当变量名与其他非变量名的字符混在一起时,需要使用{}分隔。

    hello = 3 # 错误 等会两边不可以有空格
    hello1=3  #正确 
    echo $hello1 #调用变量提前变量的值
    
    • 1
    • 2
    • 3

    常见的系统预设变量

    变量名描述
    UID当前账户uid
    USER当前账户名
    HOMEhome路径
    LANG当前系统语言
    PATH命令所搜路径
    PWD当前路径
    RANDOM随机数
    $0当前命令的名称
    $n第n个位置参数
    $?上一个命令运行的状态,0成功 1 失败
    $#参数个数
    $*所有参数
    $$返回当前进程id
    $!最后一个进程id

    二、脚本基础

    1.条件判断

    在Shell中可以使用多种方式进行条件判断,如

    1、[[表达式]]

    2、[表达式]或

    3、test表达式。

    使用条件表达式可以测试文件属性,进行字符或数字的比较。需要注意的是,不管使用哪种方式进行条件判断,系统默认都不会有任何输出结果,可以通过echo $?命令,查看上一条命令的退出状态码,或者使用&&和||操作符结合其他命令进行结果的输出操作。

    如果需要在一行代码中输入多条命令,在Shell中可以使用;(分号)、&&(与)、||(或)这三个符号将多个命令分隔。其中;(分号)是按顺序执行命令,分号前后的命令可以没有任何逻辑关系。例如,输入“A命令;B命令”,系统会先执行A命令,不管A命令执行结果如何,都会执行B命令。整个命令的退出码以最后一条命令为准,B命令如果执行成功则退出码为0, B命令如果执行失败则退出码为非0。而使用&&(与)符号分隔多条命令时,仅当前一条命令执行成功后,才会执行&&后面的命令。例如,输入“A命令&&B命令”,系统会先执行A命令,如果A命令执行成功则执行B命令,如果A命令执行失败则不执行B命令。而整行命令的退出码取决于两条命令是否同时执行成功,如果A命令执行成功并且B命令执行也成功,则整行命令的退出码为0,而A命令或B命令中的任何一条命令执行失败,则整行命令的退出码为非0。如果使用||(或)符号分隔多条命令,仅当前一条命令不执行或执行失败后才执行后一条命令。

    ;分号顺序执行

    && 成功才继续执行

    || 不执行或失败才继续执行

    2.字符串的判断比较

    test a == a # 判断字符串是否相等   测试代码 等会前后一定要有空格 ; 赋值才没空格
    echo $? 
    [$USER == root]
    echo $?
    
    [[$USER == root]] && echo y || echo n 
    [$USER != root] && echo y || echo n 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    整数的比较运算符

    符号含义
    -eq等于
    -ne不等于
    -gt大于
    -ge大于等于
    -lt小于
    -le小于等于

    文件属性判断操作符

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O6fQlCwN-1660468289839)(C:\Users\liwei\AppData\Roaming\Typora\typora-user-images\image-20220814160047841.png)]

    # 判断文件是否存在
    [-e file.txt] && echo y || echo n
    # 判断目录是否存在
    [-e /home] && echo y || echo n
    
    • 1
    • 2
    • 3
    • 4

    3.单分支if语句

    对于简单的条件判断,结合&&和||就可以完成大量的脚本。但是当脚本越写越复杂、功能越写越完善时,简单的&&和||就不足以满足需求了。此时,选择使用if语句结合各种判断条件,功能会更加完善和强大。在Shell脚本中if语句有三种格式,分别是单分支if语句、双分支if语句和多分支if语句。下面是单分支if语句的语法格式。

    if 条件语句

    then

    ​ 命令序列

    fi

    if和then可以写同一行用 分号隔开

    if 条件语句;then

    ​ 命令序列

    fi

    #!/bin/bash
    read -p "请输入用户名:" username
    read -s -p "请输入密码" password
    if [! -z "$username"];then
    	useradd "$username"
    fi
    if [! -z "$password"];then
    	echo "$password" |passwd --stdin "$username"
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    #!/bin/bash
    read -p "user" username
    read -s -p "password" password
    if [[ ! -z "$username" && ! -z "$password" ]];then  #注意此处 要用双[[]] ,注意空格
    	useradd "$username"
    	echo "$password" | passwd --stdin "$username"
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.双分支if语句

    与单分支if语句的格式一样,then和if可以写在同一行,也可以分开写在不同行。甚至在else和命令序列1中间添加分号将其写在同一行,但很少有人这样写,这将导致代码的可读性非常差。

    if 条件测试 ;then

    ​ 命令序列1

    else

    ​ 命令序列2

    fi

    #!/bin/bash
    if [ ! -z $1 ];then
    	echo "参数不为空"
    else
    	echo "参数为空"
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5.多分枝if语句

    if的双分支语法结构仅可以对事务的正确与错误两种情况做出回应,而现实问题往往更复杂,比如数字的大于、小于、等于判断。多分支if语句支持else if(简写elif)子句,可以实现在else中内嵌if的功能。在多分支if语句中elif可以出现多次,实现多次测试判断的效果。首先,来看看多分支if语句的语法格式。

    if 条件测试 ;then

    ​ 命令序列1

    elif

    ​ 命令序列2

    elif

    ​ 命令序列3

    else

    ​ 命令序列n

    fi

    #!/bin/bash
    read -p "请输入分数" score
    if [[ $score -gt 90 ]];then
            echo "优秀"
    elif [[ $score -gt 80 ]];then
            echo "良好"
    elif [[ $score -gt 70 ]];then
            echo "中等"
    elif [[ $score -ge 60 ]];then
            echo "及格"
    else
            echo "不及格"
    fi
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    6.case语句

    case语句语法格式

    case word in

    模式1 )

    ​ 命令1;;

    模式2)

    ​ 命令2;;

    *)

    ​ 命令n;;

    esac

    case支持多个条件匹配

    case word in

    模式1|模式2|模式3)

    ​ 命令1 ;;

    模式4|模式5|模式6)

    ​ 命令2;;

    *)

    ​ 命令n;;

    esac

    #!/bin/bash
    read -p "输入一个a-f 的字母" key
    case $key in 
    a)
            echo "i am a";;
    b)
            echo "i am b";;
    c|d|e|f)
            echo "i am in cdef";;
    *)
            echo "out of range";;
    esac
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    7.实例

    #!/bin/bash
    if [[ $# -lt 1 ]];then
            echo "请输入参数执行脚本时"
            exit 1
    fi
    zifu=$1
    case $zifu in
    [a-z])
            echo "小写字母";;
    [A-Z])
            echo "大写字母";;
    [0-9])
            echo "数字";;
    *)
            echo "OTHERS"
    esac
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    三、循环体

    1.for循环

    2.嵌套循环

    3.while循环

    4.untile和select循环

    5.终端与推出控制

    四、数组、subshell、函数

    五、一大波脚本技巧

    六、sed专项总结

    七、awk语法

  • 相关阅读:
    已解决json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
    shell反弹
    SQL之数据库连接
    uniapp实现大气质量指标图(app端小程序端均支持,app-nvue不支持画布)
    给兄弟们更新一点干货,工作两年在外了解到的薪资待遇和技术
    EasyExcel 导出冻结指定行
    网管软件有什么?网管软件推荐
    C#学习 - 方法的定义、调用、调试
    AVX图像算法优化系列二: 使用AVX2指令集加速查表算法。
    【零基础入门MyBatis系列】第十一篇——动态SQL
  • 原文地址:https://blog.csdn.net/weixin_42439274/article/details/126333772