• Linux/C 高级——shell脚本


    1. shell脚本基础概念

    1.1概念

    shell使用方式:手动下命令和脚本

    脚本本质是一个文件,文件里面存放的是特定格式的指令,系统可以使用脚本解析器翻译或解析指令并执行(它不需要编译)。

    shell脚本本质:shell命令的有序集合,扩展名可以为sh见名知意,也可以没有。

    shell 既是应用程序,又是一种脚本语言(应用程序 解析 脚本语言)。

    编译型语句:编译器gcc, g++

    解释型语句:不需要编译,解释一条执行一条,python、shell脚本。

    1.2创建和执行

    新建一个shell脚本: touch xx.sh

    第一行为: #!/bin/bash

    意思是使用/bin/bash来解释执行

    执行方式:

    1. sudo chmod 权限 xx.sh #使脚本具有执行权限
    2. ./xx.sh #执行脚本

    练习:

    1)在当前路径下创建file_1到file_5, 5个普通文件

    2)删除 file_2和file_3文件(使用通配符)

    3)将剩下的file文件用tar压缩成bz2的格式

    4)将压缩文件复制到家目录下

    5)进入到家目录解压压缩文件

    6)删除压缩包

    2.变量

    2.1用户自定义变量

    名命一般用大写

    进行赋值时用=,左右两边不能有空格

    引用变量在变量名前面加$

    2.2位置变量

    $0或者${0}代表包含脚本文件名的命令行参数./xx.sh

    $1,$2...代表第二个命令行参数、第三个命令行参数以此类推

    $# 代表命令行参数个数(不包含第一个也就是带脚本名的命令行参数)

    $@或者$* 代表所有命令行参数(不包含第一个也就是带脚本名的命令行参数)

    2.3预定义变量

    $? 代表前一个命令的退出状态(0为真,非0为假)

    $$ 代表执行进程的ID号

    2.4环境变量

    变量没有类型,都看作是字符串。

    环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。

    HOME: /etc/passwd文件中列出的用户主目录

    PATH :shell搜索路径,就是是一系列目录,当执行命令时,linux就在这些目录下查找。

    3.功能语句

    3.1说明性语句

    以#开头

    注释用#

    3.2功能性语句

    3.2.1 read

    功能:read从标准输入读入一行,并赋值给后面的变量

    格式:read 变量列表

    把读入行中的第一个单词赋值给第一个变量,第二个单词赋值给第二个变量以此类推

    read -p "提示语句" 变量列表: 可以将提示语句输出,同时输入变量

    3.2.2 expr

    expr 表达式

    注意:表达式符号之间必须有空格,元素引用用$

    可以直接输出结果,不过脚本里一般结合命令置换符把结果重新赋值给其他变量

    算术运算符命令expr主要用于进行简单的整数运算,包括加(+)、减(-)、乘(\*)、整除(/)和取余数(%)等操作。注意小圆括号()前面也要加转义符\。

    例子:

    练习1:通过expr实现变量自加运算(++i)

    练习2:计算表达式值a*b+c-d/b,a=2,b=3,c=15,d=18

    要求:

    1)从终端读入4个数a,b,c,d

    2)进行运算

    3)打印结果输出到终端

    1. #!/bin/bash
    2. I=0
    3. #I=`expr $I + 1`
    4. ((++I ))
    5. echo $I
    6. read -p "input: " a b c d
    7. #NUM=`expr $a \* $b + $c - $d / $b`
    8. ((NUM=a*b+c-d/b))
    9. #NUM=$((a*b+c-d/b))
    10. echo $NUM

    也可以用(())进行数学运算

    3.2.3 let

    let 表达式

    3.2.4 test

    可测试对象三种:字符串 整数 文件属性

    每种测试对象都有若干测试操作符

    1)字符串的测试:

            s1 = s2 测试两个字符串的内容是否完全一样

            s1 != s2 测试两个字符串的内容是否有差异

            -z s1 测试s1 字符串的长度是否为0

            -n s1 测试s1 字符串的长度是否不为0

    2)整数的测试:

            a -eq b 测试a 与b 是否相等 equal

            a -ne b 测试a 与b 是否不相等 not equal

            a -gt b 测试a 是否大于b greater than

            a -ge b 测试a 是否大于等于b greater equal

            a -lt b 测试a 是否小于b litter than

            a -le b 测试a 是否小于等于b litter equal

    3)文件属性的测试:

            -d name 测试name 是否为一个目录

            -f name 测试name 是否为普通文件

            -e name 测试文件是否存在

    1. #!/bin/bash
    2. #测试字符串
    3. VAR="hello"
    4. test $VAR = "hello"
    5. echo $?
    6. test $VAR != "hello"
    7. echo $?
    8. test -z $VAR
    9. echo $?
    10. test -n $VAR
    11. echo $?
    12. #测试整数
    13. test 10 -eq 5
    14. echo $?
    15. test 10 -ne 5
    16. echo $?
    17. test 10 -gt 5
    18. echo $?
    19. test 10 -lt 5
    20. echo $?
    21. #测试文件属性
    22. read -p "input filename: " FILE
    23. test -e $FILE
    24. echo $?
    25. test -f $FILE
    26. echo $?
    27. test -d $FILE
    28. echo $?

    3.3结构性语句

    3.3.1 if语句

    基本结构:

    1. if 条件
    2. then
    3. 命令表1
    4. else
    5. 命令表2
    6. fi

    多路分支结构:

    1. if 条件1
    2. then
    3. 命令表1
    4. elif 条件2
    5. then
    6. 命令表2
    7. fi

    嵌套结构:

    1. if 条件1
    2. then
    3. if 条件2
    4. then
    5. 命令表1
    6. fi
    7. else
    8. 命令表2
    9. fi

    例子:

    补充操作符:

    -o 或运算 例如 [ $a -lt 20 -o $b -gt 100 ] 返回 true

    -a 与运算 例如 [ $a -lt 20 -a $b -gt 100 ] 返回 false

    ! 非运算 例如 [ ! false ] 返回 true

    && 逻辑与 例如 [[ $a -lt 100 && $b -gt 100 ]] 返回 false

    || 逻辑或 例如 [[ $a -lt 100 || $b -gt 100 ]] 返回 true

    | 位或 例如 echo $[2|2]

    &位与 例如 echo $[2&1]

    3.3.2 case语句

    格式:

    1. case 变量 in
    2. 模式1
    3. 命令表1
    4. ;;
    5. 模式2)
    6. 命令表2
    7. ;;
    8. *)
    9. 命令表n
    10. ;;
    11. esac

    例子:

    练习:学生成绩管理系统,用shell中的case实现

    90-100:A

    80-89:B

    70-79:C

    60-69:D

    <60:不及格

    1. #!/bin/bash
    2. read -p "input score: " SCORE
    3. case $SCORE in
    4. 100|9[0-9])
    5. echo "A"
    6. ;;
    7. 8[0-9])
    8. echo "B"
    9. ;;
    10. 7[0-9])
    11. echo "C"
    12. ;;
    13. 6[0-9])
    14. echo "D"
    15. ;;
    16. [0-9]|[1-5][0-9])
    17. echo "lost"
    18. ;;
    19. *)
    20. echo "input err"
    21. ;;
    22. esac

    3.3.3 for循环

    格式:

    1. for 变量名 in 单词表
    2. do
    3. 命令表
    4. done

    变量依次取单词表中的各个单词, 每取一次单词, 就执行一次循环体中的命令。循环次数由单词表中的单词数确定。命令表中的命令可以是一条, 也可以是由分号或换行符分开的多条。

    例子:

    for语句的几种书写格式:

    1)for i in 1 2 3 4 do....done :

    变量i从单词表中取值

    2)for i do...done:

    变量i从命令行取值,可以省略in单词表

    3)for i in {1..10} do...done:

    变量i从1-10个数中取值

    4)for ((i = 0; i < 10; i++)) do...done:

    书写格式类似c语言

    3.3.4 while

    格式

    1. while 命令或表达式
    2. do
    3. 命令表
    4. done

    while语句首先测试其后的命令或表达式的值,如果为真,就执行一次循环体中的命令,然后再测试该命令或表达式的值,执行循环体,直到该命令或表达式为假时退出循环。

    练习:分别用for和while实现1-10求和

    1. #!/bin/bash
    2. i=1
    3. SUM=0
    4. while test $i -le 10
    5. do
    6. #((SUM=SUM+i))
    7. #SUM=`expr $SUM + $i`
    8. let SUM=SUM+i
    9. ((i++))
    10. done
    11. echo $SUM
    12. SUM=0
    13. ##################################
    14. for ((i=1;i<=10;i++))
    15. do
    16. ((SUM=SUM+i))
    17. done
    18. echo $SUM

    3.3.5 循环控制语句

    break n: 结束n层循环

    continu n: 结束n层的本次循环,继续下一次循环

    1. #!/bin/bash
    2. for ((i=0;i<5;i++))
    3. do
    4. for((j=0;j<5;j++))
    5. do
    6. if [ $j -eq 3 ]
    7. then
    8. #break 1
    9. #break 2
    10. #continue 1
    11. continue 2
    12. fi
    13. echo "$i : $j" #4 2
    14. done
    15. done

    4.数组

    4.1数组的赋值

    a. 直接对数组赋值:

            arr=(1 2 3 4 5)

    b. 把命令行参数赋值给数组:

            arr=($1 $2 $3)

    c. 把元素赋值给数组:

            read a b c

            arr=($a $b $c)

    d. 给数组元素输入赋值:

            read -a arr

    4.2数组的调用

    ${arr[i]} #访问数组元素,数组下标从0开始到n-1结束

    arr[i]=10 #对数组元素重新赋值

    ${arr[@]} #遍历数组

    ${#arr[@]} #表示数组元素的个数

    练习:从终端输入3个整数,输出三个数中的最小值

    1. #!/bin/bash
    2. read -a arr
    3. MIN=${arr[0]}
    4. n=${#arr[@]}
    5. for ((i=0;i
    6. do
    7. if [ $MIN -gt ${arr[i]} ]
    8. then
    9. MIN=${arr[i]}
    10. fi
    11. done
    12. echo $MIN

    冒泡排序:

    练习:用shell脚本试下以下功能:

    判断当前路径下是否存在目录aa,如果不存在创建;遍历当前路径下的文件,如果是普通文件,将文件复制到aa目录下,并计算文件的个数。

    1. #!/bin/bash
    2. if [ -d aa ] #如果当前目录下有aa目录就删除然后创建
    3. then
    4. rm -r aa
    5. fi
    6. mkdir aa
    7. num=0
    8. filelist=`ls` #将当前目录下所有文件赋值给filelist变量
    9. for file in $filelist #for file in * #用file遍历当前目录下所有文件
    10. do
    11. if [ -f $file ] #如果是普通文件就复制到aa目录下
    12. then
    13. cp $file ./aa
    14. ((num++)) #计算文件个数
    15. fi
    16. done
    17. echo $num

  • 相关阅读:
    支持JDK19虚拟线程的web框架,之一:体验
    点餐小程序实战教程01需求分析
    使用 Promise 来改写 JavaScript 的加载逻辑
    [附源码]Python计算机毕业设计Django的玉石交易系统
    83、SpringBoot --- 下载和安装 MSYS2、 Redis
    javascript--async和defer的区别
    相机、雷达、ROS坐标系之间的关系
    如何调试JNI程序
    CSDN博客编写的相关操作
    Android 11.0 framework添加自定义开机广播
  • 原文地址:https://blog.csdn.net/weixin_48633411/article/details/141000274