• shell脚本编程基础(上)


    目录

    (一)shell介绍

    1.什么是shell

     扩展知识

    2. shell功能

    (二)shell语法

    2.1 如何书写一个shell脚本

    0x01 shell脚本的命名:

    0x02 shell脚本格式:

    0x03 shell中的注释使用#号

    2.2 如何运行一个shell脚本

    2.3 shell中的特殊符号

    2.4 shell中管道的运用

    2.5  shell重定向

    2.6  shell数学运算

    2.7 退出脚本

    (三) shell格式化输出

    0x01. echo命令介绍

    0x02 颜色代码

    格式如下:

    (四)shell基本输入

    1. read命令

    (五)shell变量

    1.变量介绍

    2.变量分类

    3.定义变量

    3.1定义变量

    3.2读取变量内容

    3.3 取消变量unset

    3.4定义全局变量export

    3.5定义永久变量

    (六)shell数组

    0x01.数组介绍

    0x02.基本数组

    2.1数组语法

    2.2数组读出

    2.3数组赋值

    方法二: 一次赋多个值

    2.4查看数组

    2.5访问数组元素

    2.6遍历数组

    0x03.关联数组

    3.1定义关联数组

    3.2关联数组赋值

    3.3查看数组

    3.4访问数组元素

    3.5遍历数组

    0x04.案例分享——学员信息系统

    (七)、shell流程控制-if判断语句

    0x01. shell中的运算

    1.1数学比较运算

    1.2字符串比较运算

    1.3 文件比较与检查

    1.4 逻辑运算

    1.5 赋值运算

    0x02. if语法

    2.1语法一:单if语句

    2.2语法二:if-then-else语句

    2.3语法三:if-then-elif语句

    0x03. if高级应用


    (一)shell介绍


    1.什么是shell


    shell是一个程序,采用C语言编写,是用户和Linux内核沟通的桥梁。它既是一种命令语言,又是一种解释性的编程语言。通过一个图标来查看以下设立了的作用,如图1-1

    图1-1 shell的执行过程

     扩展知识

    • kernel(内核):为软件服务,接收用户或软件指令驱动硬件,完成工作;
    • shell:命令解释器
    • user:用户接口,对接用户

    从上图可以看出,shell在操作系统中起到了承接用户和系统内核的作用。那为什么步直接用户对内核呢?

    原因很简单,因为内核处理的都是二进制,而用户处理的都是高级语言。简而言之,如果没有shell,你希望告诉你喜欢的妹子:我爱你。你需要经过以下步骤:

    1. 将“我爱你”翻译成二进制
    2. 告诉内核
    3. 内核通过网卡发送给你的妹子
    4. 妹子计算机网卡收到你发的二进制
    5. 网卡交给内核
    6. 内核交给妹子
    7. 妹子看到都是一串01组成的数字,o my god,二进制不是人人都懂的,你的表白也就石沉大海了。

    为了让所有人都能够快速、方便地使用计算机,我们开发的系统,开发人员通过shell解决了这个问题。使任何一个希望通过计算机来工作、娱乐的人都能够快速操作计算机。

    2. shell功能


    • 命令行解释功能
    • 启动程序
    • 输入输出重定向
    • 管道连接
    • 文件名置换(echo /*)
    • 变量维护
    • 环境控制
    • shell编程

    (二)shell语法


    shell脚本就是将完成一个任务的所有命令按照执行的先后顺序,自上而下写入到一个文本文件中,然后给予执行权限。

    2.1 如何书写一个shell脚本


    0x01 shell脚本的命名:

    名字要有意义,最好不要用a、b、c、d、1、2、3、4这中方式命名;虽然在linux系统中,文件没有扩展名的概念,依然建议你用.sh结尾;名字不要太长,最好能在30个字节以内解决。例如check_memory.sh

    0x02 shell脚本格式:

    shell脚本开头必须指定脚本运行环境,以#!这个特殊符号组合了组成。如: #!/bin/bash 指定该脚本是运行解析由/bin/bash来完成的:

    0x03 shell中的注释使用#

    #后面加上注释内容

    2.2 如何运行一个shell脚本


    • 脚本运行需要执行权限,当我们给一个文件赋予执行权限后,该脚本就可以运行
    chmod u+x filename
    • 如果不希望赋予脚本执行权限,那么可以使用bash命令来运行未给予执行权限的脚本
    bash filename

    2.3 shell中的特殊符号


    符号描述
    ~家目录 # cd ~ 代表进入用户家目录
    !执行历史命令 ~~执行上一条命令
    $变量中取内容符
    + – * / %对应数学运算 加 减 乘 除 取余
    &后台执行
    *星号是shell中的通配符,匹配所有
    ?问号是shell中的通配符,匹配除回车以外的一个字符
    ;分号可以在shell中一行执行多个命令,命令hi加用分号分隔
    |管道符,上一个命令的输出作为下一个命令的输入 cat filename | grep “abc”
    \转义字符
    ` | 反引号 命令中执行命令 echo “today is /date +%F/`”
    ‘ ‘单引号,脚本中字符串要用单引号引起来,但不同于双引号的是,单引号不解释变量
    ” “双引号,脚本中出现的字符串可以用双引号引起来

    2.4 shell中管道的运用


    | 管道符在shell中使用是最多的,很多组合命令都需要通过组合命令来完成输出。管道符其实就是下一个命令对上一个命令的输出做处理。

    2.5  shell重定向


    1. > 重定向输入 覆盖原数据
    2. >> 重定向追加输入,在原数据的末尾添加
    3. < 重定向输出 wc -l < /etc/passwd
    4. << 重定向追加输出 fdisk << /dev/sdb

    2.6  shell数学运算


    • expr 命令:只能做整数运算,格式比较古板,注意空格
    1. expr 1 + 1
    2. expr 5 - 2
    3. expr 5 \* 2
    4. expr 5 / 2
    5. expr 5 % 2

    • 使用bc计算器处理浮点运算,sacle=2代表小数点保留两位
    1. echo "scale=2;3+100"|bc
    2. echo "scale=2;100-3"|bc
    3. echo "scale=2;100/3"|bc
    4. echo "scale=2;100*3"|bc

    • 双小圆括号运算,在shell中(())也可以用来做数学运算
    1. echo $(( 100+3))
    2. echo $(( 100-3))
    3. echo $(( 100%3))
    4. echo $(( 100*3))
    5. echo $(( 100/3))
    6. echo $(( 100**3)) //开方运算

    2.7 退出脚本


    • exit NUM:退出脚本,释放系统资源,NUM代表一个整数,代表返回值。

    (三) shell格式化输出


    • echo命令
    • 颜色输出

    0x01. echo命令介绍


    echo命令的功能是在显示器上显示一段文字,一般起到一个提示的作用。 该命令的一般格式为:echo [ -n ]字符串

    其中选项n表示输出文字后不换行;字符串能加引号,也能不加引号。用echo命令输出加引号的字符串时,将字符串原样输出;用echo命令输出不加引号的字符串时,将字符串中的各个单词作为字符串输出,各字符串之间用一个空格分割。

    • 功能说明:显示文字。
    • 语法:
    1. echo [-ne][字符串]
    2. echo [--help][--version]

    补充说明:echo会将输入的字符串送往标准输出。输出的字符串间以空白字符隔开,并在最后加上换行号

    命令选项:

    -n:不要在最后自动换行;

    -e:若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出:

    ​ 转义字符:

     举例:输出一个菜单

    1. #!/bin/bash
    2. echo -e "\t\t\t\tFruit Shop"
    3. echo -e "\t1) Apple"
    4. echo -e "\t2) Orange"
    5. echo -e "\t3) Banana"

    输出

    1. Fruit Shop
    2. 1) Apple
    3. 2) Orange
    4. 3) Banana

    0x02 颜色代码


    脚本中echo显示内容带颜色显示,echo显示带颜色,需要使用参数-e

    格式如下:

    echo -e “\033[字背景颜色;文字颜色m字符串\033[0m”

    例如:

    echo -e “\033[41;36m something here \033[0m”
    1. 字背景颜色和文字颜色之间是英文的””
    2. 文字颜色后面有个m
    3. 字符串前后可以没有空格,如果有的话,输出也是同样有空格
    1. 下面是相应的字和背景颜色,可以自己来尝试找出不同颜色搭配
    2.   例
    3.   echo -e “\033[31m 红色字 \033[0m”
    4.   echo -e “\033[34m 黄色字 \033[0m”
    5.   echo -e “\033[41;33m 红底黄字 \033[0m”
    6.   echo -e “\033[41;37m 红底白字 \033[0m”
    7.   
    8. 字颜色:30—–37
    9.   echo -e “\033[30m 黑色字 \033[0m”
    10.   echo -e “\033[31m 红色字 \033[0m”
    11.   echo -e “\033[32m 绿色字 \033[0m”
    12.   echo -e “\033[33m 黄色字 \033[0m”
    13.   echo -e “\033[34m 蓝色字 \033[0m”
    14.   echo -e “\033[35m 紫色字 \033[0m”
    15.   echo -e “\033[36m 天蓝字 \033[0m”
    16.   echo -e “\033[37m 白色字 \033[0m”
    17.   
    18. 字背景颜色范围:40—–47
    19.   echo -e “\033[40;37m 黑底白字 \033[0m”
    20.   echo -e “\033[41;37m 红底白字 \033[0m”
    21.   echo -e “\033[42;37m 绿底白字 \033[0m”
    22.   echo -e “\033[43;37m 黄底白字 \033[0m”
    23.   echo -e “\033[44;37m 蓝底白字 \033[0m”
    24.   echo -e “\033[45;37m 紫底白字 \033[0m”
    25.   echo -e “\033[46;37m 天蓝底白字 \033[0m”
    26.   echo -e “\033[47;30m 白底黑字 \033[0m”
    27.   
    28. 最后面控制选项说明
    29.   \033[0m 关闭所有属性
    30.   \033[1m 设置高亮度
    31.   \033[4m 下划线
    32.   \033[5m 闪烁
    33.   \033[7m 反显
    34.   \033[8m 消隐
    35.   \033[30m — \33[37m
    36. 设置前景色
    37.   \033[40m — \33[47m 设置背景色
    38.   \033[nA 光标上移n行
    39.   \033[nB 光标下移n行
    40.   \033[nC 光标右移n行
    41.   \033[nD 光标左移n行
    42.   \033[y;xH设置光标位置
    43.   \033[2J 清屏
    44.   \033[K 清除从光标到行尾的内容
    45.   \33[s 保存光标位置
    46.   \033[u 恢复光标位置
    47.   \033[?25l 隐藏光标
    48.   \033[?25h 显示光标

    (四)shell基本输入


    1. read命令

    默认接受键盘的输入,回车符代表输入结束

    (五)shell变量


    1.变量介绍

    1. 在编程中,我们总有一些数据需要临时存放在内存,以待后续使用时快速读出。内存在系统启动的时候被按照1B一个单位划分为若干个块,然后统一
    2. 编号(16进制编号),并对内存的使用情况做记录,保存在内存跟踪表中

    变量:变量是编程中最常用的一种临时在内存中存取数据的一种方式。

     从图片可以看出,当我们在脚本中定义变量存值的时候,可以从以下方面看到变化:

    1. 内存占用:如果存的是一个字符则占用1个字节,如果存的是字符串则是字符串的长度加1个字节长度(\0是一个特殊字符,代表字符串结束)。
    2. 变量名与内存空间关系:计算机中会将对应的内存空间和变量名称绑定在一起,此时代表这段内存空间已经被程序占用,其他程序不可复用;然后将变量名对应的值存在对应内存地址的空间里。

    2.变量分类


    1. 本地变量:用户私有变量,只有本用户可以使用,保存在家目录下的.bash_profile、.bashrc文件中
    2. 全局变量:所有用户都可以使用,保存在/etc/profile、/etc/bashrc文件中
    3. 用户自定义变量:用户自定义,比如脚本中的变量

    3.定义变量


    3.1定义变量

    变量格式:变量名=值

    在shell编程中的变量名和等号之间不能有空格

    变量命名规则:

    1. 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
    2. 中间不能有空格,可以使用下划线(_)。
    3. 不能使用标点符号。
    4. 不能使用bash里的关键字(可用help命令查看保留关键字)。
    1. VAR1=1
    2. age=18
    3. name='baism'
    4. score=88.8

    注意:字符串要用单引号或双引号引起来

    3.2读取变量内容

    • 读取变量内容符:$
    • 读取方法:$变量名
    1. echo $name
    2. echo $school
    3. echo $age
    4. echo $score

    3.3 取消变量unset

    1. unset name
    2. echo $name

    3.4定义全局变量export

    export name='Tom'

    注意

    1. 上述设置的变量其实都是一次性变量,系统重启就会丢失。
    2. 如果希望本地变量或者全局变量可以永久使用,可以将需要设置的变量写入变量文件中即可。

    3.5定义永久变量

    本地变量:用户私有变量,只有本用户可以使用,保存在家目录下的.bash_profile、.bashrc文件中

    全局变量:所有用户都可以使用,保存在/etc/profile、/etc/bashrc文件中

    1. #本地变量
    2. tail -1 ~/.bash_profile
    3. name='baism'
    4. #全局变量
    5. tail -1 /etc/profile
    6. export age=30

    (六)shell数组


    0x01.数组介绍

            一个变量只能存一个值,但是现实中又又很多值需要存储,那么变量就有些拘谨了。比如做一个学员信息表,一个班50个人,每个人6条信息,我们需要定义300个变量才能完成。恐怖恐怖,这只是一个班的学生,一个学校呢?一个市呢?……

    仔细想想上述的案例,一个学生六个信息:ID、姓名、性别、年龄、成绩、班级。可不可以定义六个变量就能存储这六类信息呢?答案是当然可以的!变量不行,我们就用数组。

    0x02.基本数组


    数组可以让用户一次赋予多个值,需要读取数据时只需通过索引调用就可以方便读出了

    2.1数组语法

    数组名称=(元素1 元素2 元素3 ...)

    2.2数组读出


    ${数组名称[索引]}

    索引默认是元素在数组中的排队编号,默认第一个从0开始

    2.3数组赋值


    方法一:一次赋一个值

    1. array0[0]='tom'
    2. array0[1]='jarry'
    3. array0[2]='natasha'

    方法二: 一次赋多个值

    1. array2=(tom jack alice)
    2. array3=(cat /etc/passwd) #希望是将该文件中的每一个行作为一个元素赋值给数组array3
    3. array4=(ls /var/ftp/Shell/for*)
    4. array5=(tom jack alice “bash shell”)

    2.4查看数组

    1. declare -a
    2. declare -a array1='([0]=”pear” [1]=”apple” [2]=”orange” [3]=”peach”)'
    3. declare -a array2='([0]=”tom” [1]=”jack” [2]=”alice”)'

    2.5访问数组元素

    1. echo ${array1[0]} #访问数组中的第一个元素
    2. echo ${array1[@]} #访问数组中所有元素 等同于 echo ${array1[*]}
    3. echo ${#array1[@]} #统计数组元素的个数
    4. echo ${!array2[@]} #获取数组元素的索引
    5. echo ${array1[@]:1} #从数组下标1开始
    6. echo ${array1[@]:1:2} #从数组下标1开始,访问两个元素

    2.6遍历数组

    默认数组通过数组元素的个数进行遍历

    1. echo ${ass_array2[index1]}
    2. echo ${ass_array2[index2]}
    3. echo ${ass_array2[index3]}
    4. echo ${ass_array2[index4]}

    0x03.关联数组

    关联数组可以允许用户自定义数组的索引,这样使用起来更加方便、高效。

    3.1定义关联数组

    申明关联数组变量

    1. declare -A ass_array1
    2. declare -A ass_array2

    3.2关联数组赋值

    方法一: 一次赋一个值

    1. 数组名[索引]=变量值
    2. ass_array1[index1]=pear
    3. ass_array1[index2]=apple
    4. ass_array1[index3]=orange
    5. ass_array1[index4]=peach

    方法二: 一次赋多个值

    ass_array2=([index1]=tom [index2]=jack [index3]=alice [index4]=’bash shell’)

    3.3查看数组

    1. declare -A
    2. declare -A ass_array1=’([index4]=”peach” [index1]=”pear” [index2]=”apple” [index3]=”orange” )’
    3. declare -A ass_array2=’([index4]=”bash shell” [index1]=”tom” [index2]=”jack” [index3]=”alice” )’

    3.4访问数组元素

    1. echo ${ass_array2[index2]} #访问数组中的第二个元数
    2. echo ${ass_array2[@]} #访问数组中所有元数 等同于 echo ${array1[*]}
    3. echo ${#ass_array2[@]} #获得数组元数的个数
    4. echo ${!ass_array2[@]} #获得数组元数的索引

    3.5遍历数组

    通过数组元数的索引进行遍历,针对关联数组可以通过数组元素的索引进行遍历

    1. echo ${ass_array2[index1]}
    2. echo ${ass_array2[index2]}
    3. echo ${ass_array2[index3]}
    4. echo ${ass_array2[index4]}

    0x04.案例分享——学员信息系统


    1. #!/bin/bash
    2. for ((i=0;i<3;i++))
    3. do
    4. read -p "输入第$((i + 1))个人名: " name[$i]
    5. read -p "输入第$[$i + 1]个年龄: " age[$i]
    6. read -p "输入第`expr $i + 1`个性别: " gender[$i]
    7. done
    8. clear
    9. echo -e "\t\t\t\t学员查询系统"
    10. while :
    11. do
    12. cp=0
    13. # echo -e "\t\t\t\t学员查询系统"
    14. read -p "输入要查询的姓名: " xm
    15. [ $xm == "Q" ]&&exit
    16. for ((i=0;i<3;i++))
    17. do
    18. if [ "$xm" == "${name[$i]}" ];then
    19. echo "${name[$i]} ${age[$i]} ${gender[$i]}"
    20. cp=1
    21. fi
    22. done
    23. [ $cp -eq 0 ]&&echo "not found student"
    24. done

    (七)、shell流程控制-if判断语句


    0x01. shell中的运算

    1.1数学比较运算

    运算符解释:

     

    1. test 1 -eq 1;$? #0(shell中0为真,1为假)
    2. test 1 -lt 1;$? #1

    1.2字符串比较运算

    运算符解释,注意字符串一定别忘了使用引号引起来

     

    test 'abc' -n

    1.3 文件比较与检查

     Demo:

    1. file1 -nt file2 检查file1是否比file2
    2. file1 -ot file2 检查file1是否比file2
    3. file1 -ef file2 检查file1是否与file2是同一个文件
    1. test -d /opt/shell;echo $? #0
    2. test -e /opt/shell/shell_05.sh;echo $? #0

    1.4 逻辑运算

     

    if [ 1 -eq 1 ] && [ 2 -eq 2 ];then echo "yes";else echo "no";fi        #yes

    逻辑运算注意事项:逻辑与 或 运算都需要两个或以上条件,逻辑非运算只能一个条件。

    1.5 赋值运算

    =:赋值运算符

    1. a=10
    2. name='baism'

    0x02. if语法


    2.1语法一:单if语句

    适用范围:只需要一步判断,条件返回真干什么或者条件返回假干什么。

    语句格式

    1. if [ condition ] #condition 值为true or false
    2. then
    3. commands
    4. fi

    Demo:

            判断当前用户是不是root,如果不是那么返回”ERROR: need to be root so that!“

    1. #!/bin/bash
    2. if[ $USER != 'root' ]
    3. then
    4. echo "ERROR:need to be so that"
    5. exit 1
    6. fi

    2.2语法二:if-then-else语句

    适用范围:两步判断,条件为真干什么,条件为假干什么。

    1. if [ condition ]
    2. then
    3. commands1
    4. else
    5. commands2
    6. fi

    Demo:

            判断当前登录用户是管理员还是普通用户,如果是管理员输出”hey admin“ 如果是普通用户输出”hey guest“

    1. if [ $USER == 'root' ]
    2. then
    3. echo "hey admin"
    4. else
    5. echo "hey guest"
    6. fi

    2.3语法三:if-then-elif语句

    适用范围:多于两个以上的判断结果,也就是多于一个以上的判断条件。

    1. if [ condition 1]
    2. then
    3. commands1
    4. elif [ condition 2]
    5. then
    6. commands2
    7. .......
    8. else
    9. commandsX
    10. fi

    Demo:

            通过一个脚本,判断两个整数的关系。

    1. if [ $1 -gt $2 ]
    2. then
    3. echo "$1 > $2"
    4. elif [ $1 -eq $2 ]
    5. then
    6. echo "$1 = $2"
    7. else
    8. echo "$1 < $2"
    9. fi

    0x03. if高级应用


    • 条件符号使用双圆括号,可以在条件中植入数学表达式
    1. if (( 100%3+1>1 ));then
    2. echo "yes"
    3. else
    4. echo "no"
    5. fi

    注意 双小圆括号中的比较运算符 使用的是我们传统的比较运算符 >>= == <<= !=

    • 使用双方括号,可以在条件中使用通配符

    为字符串提供高级功能,模式匹配 r* 匹配r开头的字符串

    1. #!/bin/bash
    2. for i in r1 rr2 cc rr3
    3. do
    4. if [[ $i == r* ]];then
    5. echo $i
    6. fi
    7. done

    为字符串提供高级功能,模式匹配 r* 匹配r开头的字符串

  • 相关阅读:
    【广州华锐互动】VR综合布线虚拟实验教学系统
    刷题笔记 1
    Vue搭建前端监控,采集用户行为的 N 种姿势
    Azure DevOps (八) 通过流水线编译Docker镜像
    Open Interpreter:OpenAI Code Interpreter的开源实现|本地化|可联网
    索引的数据结构(3)
    Python ElementTree 导出 xml 缺少 开头声明&【Pymssql】使用cursor.fetchall()获取执行结果时中文乱码
    shell 重定向
    JAVA集合04_Map接口概述、常用方法、排序、Hashtable面试题
    wifi6 feature 详解
  • 原文地址:https://blog.csdn.net/m0_61506558/article/details/127837596