• Shell编程-01


    目录

    一、shell的初步理解

    1、怎么理解shell

    2、shell命令

     二、shell编程

    1、什么是shell编程

    2、C语言编程 和 shell编程的区别

    3、为什么要学习shell脚本编程

    三、编写和运行第一个shell脚本程序

    1、编写时需要注意以下几点

    2、第一个shell程序 hello.sh

     3、如何运行编写好的shell程序

     四、变量

    1、shell变量不需要声明数据类型,所有的变量默认都是字符串类型

    2、shell语法中为变量赋值时,等号的左右两边不允许有空格

    3、变量的引用,需要在变量前面加入美元符号$

    4、变量种类

    1)自定义变量 ---类似 于 C语言 中的局部变量

    2)系统环境变量----env命令查看环境变量 ---类似 于 C语言 中的全局变量

    5、位置变量(传递命令行参数和函数调用时传递参数)

     五、shell编程符号

    1、双引号 --> 作用: 把某些东西 变成 "值"

    2、单引号 --->在单引号里面的内容 看做是纯粹的字符串

    3、反引号--->把双引号中的命令标识出来,也就是将反引号中的内容当成一个shell命令进行解析 

     4、重定向符号 < << > >>

    1)输出重定向 > >>

    2)输入重定向

     3)标准出错重定向

     六、算术运算命令expr

    七、字符串处理  

    八、获取输入 

    九、test语句

    1、字符串测试

    2、整数测试 

    3、文件测试  

    1)使用test内置的操作符

     2)使用条件操作符(&& || !)

    十、if分支语句

    十一、多路分支语句

    1、格式

    2、总结

    3、例子

    十二、循环语句

    1、for循环

    2、while循环

    3、 until

    4、break 和 continue

    十三、函数


    一、shell的初步理解

    1、怎么理解shell

    shell在英文中翻译为"贝壳",在贝壳内部就是linux系统内核,在贝壳外部就是用户。对于shell而
    言,就是用户与内核之间的媒介。

    2、shell命令

    Linux命令指的是shell命令,大多数shell命令都是存放在/bin,当我们需要使用一个命令时,实际
    的流程:

     二、shell编程

    1、什么是shell编程

    shell编程就是通过shell语法将shell命令组合起来,写入一个文件中。将来运行这个文件时,就会执行
    里面的每一行shell语法,这个文件称之为shell脚本文件。实现更加自动化和智能化。

    2、C语言编程 和 shell编程的区别

    C语言程序 shell脚本程序
    语法 C语言语法 shell语法
    文件后缀 xxx.c xxx.sh
    文件存放位置 任意目录 除了共享目录之外,一般放在家目录
    是否需要编译 gcc编译 不需要编译,但是需要给权限

    3、为什么要学习shell脚本编程

    当前IT服务器百分之80都是linux服务器。linux服务器的日常维护和管理需要linux运维工程师,让程序
    员写的代码能够高效、稳定、安全地在服务器上运行。
    Linux运维工程师(OPS):
    安装操作系统 Centos Ubuntu
    部署代码运行环境,比如网站后台
    及时修复漏洞,防止服务器被攻击,包括linux本身漏洞以及软件漏洞
    监控服务器压力,别让服务器宕机。比如双十一淘宝瞬间涌入大量用户导致服务器宕机,网页无法访问或者支付宝无法使用。
    分析日志,及时发现代码或者环境的问题,通知相关人员修复。
    Linux运维工程师 日常管理的服务器 成千上万台,此时需要自动化管理跑一段代码就能在成千上万台服务器上完成相同的工作,比如服务器的监控。shell脚本就是实现Linux系统自动管理以及自动化运维所必备的工具,Linux 的底层以及基础应用软件的核心大都涉及 Shell 脚本的内容。每一个合格的Linux 系统管理员或运维工程师,都应该能够熟练的编写 Shell 脚本。

    三、编写和运行第一个shell脚本程序

    1、编写时需要注意以下几点

    1)shell脚本没有main函数,没有头文件。shell脚本文件中是使用bash解析器进行解析,所以必须在
    shell脚本中的第一行指明解析器的路径:
    #!/bin/bash
    #!是shell脚本中特殊标识符,后面必须跟着shell命令解析器的路径
    2)shell脚本中没有printf函数,要输出内容到终端上,必须使用shell命令---》echo

    2、第一个shell程序 hello.sh

    1. #!/bin/bash
    2. echo "hello world

     3、如何运行编写好的shell程序

    1)先给权限(因为默认是没有执行权限的)
    chmod 777 hello.sh 或者 chmod +x hello.sh
    2)执行
    ./hello.sh

    1. #!/bin/bash
    2. echo "GZ2264班 简健铭 来自广东"
    3. echo "大家好,我是GZ2264班的吴彦祖,这是我写的第一个shell程序"
    4. echo "作者:简健铭 职业:老六"
    5. echo "座右铭:杀人放火金腰带"

     四、变量

    1、shell变量不需要声明数据类型,所有的变量默认都是字符串类型

    1. C语言: int a;
    2. shell: str

    2、shell语法中为变量赋值时,等号的左右两边不允许有空格

    1. C语言 int a = 10;
    2. shell str=helloworld

    3、变量的引用,需要在变量前面加入美元符号$

    echo $str 或者 echo ${str}

    4、变量种类

    1)自定义变量 ---类似 于 C语言 中的局部变量

    str=hello

    2)系统环境变量----env命令查看环境变量 ---类似 于 C语言 中的全局变量

    1. HOME: 用户主目录
    2. PATH: 命令搜索路径
    3. LD_LIBRARY_PATH: 动态库搜索路径
    4. PWD: 当前路径
    使用命令改变环境变量:
    1. export PATH=$PATH:/home/china/xxx
    2. export PATH=/home/china/xxx

    5、位置变量(传递命令行参数和函数调用时传递参数)

    ./hello.sh aaaa bbbb

     注意:

            (1)在脚本中修改的环境变量只在脚本及子脚本范围内有效,要想其在外边环境中生效,则需要前面加 source
    eg: source 1.sh
            (2)如何使脚本(程序)后台执行
    a.脚本(程序)后面加&符号,但是终端退出了,该进程也会结束
     eg: ./a.out &
    b.如果想让终端退出后,进程仍在:
    eg: nohup ./a.out &
    练习3:分别使用变量和命令行传递参数输出hello world字符串
    1 变量:
    2 str = helloworld
    3 echo $str
    4 命令行:
    5 . / hello . sh helloworld
    6 echo $1
    1. #!/bin/bash
    2. #变量赋值=两边不能有空格
    3. str=helloworld
    4. #变量的引用 自定义变量需要定义来赋值
    5. echo $str
    6. #命令行传参
    7. #./shell-变量 01 02 $0-->./shell-变量 $1-->01 $2--> 02
    8. echo $0 $1 #类似于argv

     五、shell编程符号

    1、双引号 --> 作用: 把某些东西 变成 "值"

    1)例如字符串中有空格,则必须使用"",如果没有空格,不加""也可以

    2)在""内可以对变量进行引用

    1. str=hello
    2. echo "$str world"

    3)在""内部是可以使用shell命令,但是使用shell命令需要使用反引号``来括住命令

    1. #!/bin/bash
    2. str=hello
    3. #str="jjm"
    4. #str="hello world"
    5. #echo $str
    6. echo "todao is `date`"
    7. echo 'todao is date'

    2、单引号 --->在单引号里面的内容 看做是纯粹的字符串

    3、反引号--->把双引号中的命令标识出来,也就是将反引号中的内容当成一个shell命令进行解析 

     

     4、重定向符号 < << > >>

    标准输入(0)/标准输出(1)/标准输错(2) 系统默认打开的文件描述符

    1)输出重定向 > >>

    命令的输出结果通常提交到标准输出设备(终端),但是也可以重新定个方向到其他位置,比如用一个文件来代替,这叫做输出重定向。在命令后添加>filename ,该命令(脚本)的输出就会写入到
    filename这个文件中,而不是写入终端。

    2)输入重定向

    命令的输入通常是从标准输入设备(键盘)中请求的,但是也可以重新定个方向到其他位置,比如从一个文件中请求,这叫做输入重定向。命令
    比如: read str < 1. txt 1. txt 中读取数据,存储到变量 str read shell 编程中的一个函
    类似于 scanf ()

     3)标准出错重定向

    unix命令把大部分错误信息都写到这个设备里面。一般情况下,标准出错设备和标准输出设备是同一个设备(默认为终端)。标准出错也可以重定向到文件
    命令 2 > filename
    命令 2 >> filename
    4 china @ubuntu : ~/ shelldir$ asdsds 2 > a . txt -- 把出错信息重定向到文件 a . txt
    5 china @ubuntu : ~/ shelldir$ cat a . txt
    6 asdsds :未找到命令

     六、算术运算命令expr

    expr主要是用于简单的整数计算,包括 加(+)、减(-)、乘(\*)、除(/)、取余(%)
    1 #!/bin/bash
    2 a = 10
    3 b = 20
    4 val = `expr $a + $b ` ( 注意:操作数与运算符,前后至少要有一个空格 )
    5 echo "val: $val " ---> val : 30
    1 #!/bin/bash
    2 a = 10
    3 b = 20
    4 val = `expr $a + $b \ * 4 ` ( 且不支持括号 )
    5 echo "val: $val " ---> val : 90

    七、字符串处理  

    计算字符串字符个数
    1 str = "hello world"
    2 echo "${#str}" --> 11

    通配符:

    1 * 代表任意长度的任意字符
    2 ? 代表一个长度的任意字符
    3 [ a-z ]: 代表一个长度的 a-z 之内的字符
    4 [ az ]: 代表一个长度,只能匹配 a 或者 z 的内容
    5 [ ^az ]: 代表一个指定范围 a/z 之外的字符 [az] 相反!
    6
    7 %: 从右到左尽可能匹配少的字符
    8 %%: 从右到左尽可能匹配多的字符
    9 # : 从左到右尽可能匹配少的字符
    10 ## : 从左到右尽可能匹配多的字符

    八、获取输入 

    read:在shell表示从终端输入
    1 read val1
    2 read - p "input data:" val1 val2 val3
    3 read val < 1. txt // 从文本输入
    注意:
    1、以#开头的行,就是注释行
    2、多行注释:
    1 << 'COMMENT'
    2 ...
    3 COMMENT

     练习4:从键盘上获取三个同学的信息,并且打印出来

    1. #!/bin/bash
    2. # read -p "name:" val1
    3. # read -p "sex:" val2
    4. # read -p "hight:" val3
    5. # echo "***********"
    6. # echo "name:$val1 sex:$val2 hight:$val3"

    九、test语句

    test语句可以测试三种对象:字符串、整数、文件属性

    1、字符串测试

    = 测试两个字符串内容是否完全一样
    2 != 测试两个字符串内容是否不一样
    3 - Z ( zero ) 测试字符串是否为空,为空,返回 true
    4 - n ( null ) 测试字符串是否不为空,不为空,返回 true
    在测试字符串变量时,需要防止字符串为空的技巧:
    引用变量后加一个额外的字符:
    1 test $ { A } x = $ { B } x

    2、整数测试 

    1 a -eq b : equal 测试两个整数是否相等
    2 a -ne b : not equal 测试两个是否不相等
    3 a -gt b : greater 测试 a 是否大于 b
    4 a -ge b : greater or equal 测试 a 是否大于等于 b
    5 a -lt b : little 测试 a 是否小于 b
    6 a -le b : little or equal 测试 a 是否小于等于 b

    3、文件测试  

    1 - d name 测试 name 是否是一个目录 ( dir ) // if test -d 1.txt;then
    2 - f name 测试 name 是否是一个普通文件 ( file )
    3 - L name 测试 name 是否为符号链接文件 ( Link )
    4 - r name 测试 name 文件是否存在并可读 ( read )
    5 - w name 测试 name 文件是否存在并可写 ( write )
    6 - x name 测试 name 文件是否存在并可执行 ( excute )
    7 - s
    8 e 测试 name 文件是否存在并且长度不为 0 ( size )
    9 f1 - nt f2 测试 f1 是否比 f2 更新 ( newer than )
    10 f1 - ot f2 测试 f1 是否比 f2 更旧 ( older than )

    test命令可以用[]来简写

    1 test expression <===> [ expression ] 

    test的复合表达式
    组合了两个或两个以上的表达式称为复合表达式,你可以用test([])内置的的操作符,也可以用条件操
    作符(&& || !)来实现

    1)使用test内置的操作符

    test expr1 "test_buildin" expr2
    test_buildin :
    - a and
    - o or

     2)使用条件操作符(&& || !)

    test expr1 "op" test expr2

    比如: test $A = '1' && test $B = '1'
    [ $A = '1' ] && [ $B = '1' ]

     练习5: 判断一个输入的整数是否是奇数,如果是则打印yes ,否则 no

    1. #!/bin/bash
    2. read -p "input data:" val
    3. if test `expr $val % 2` -eq 0;then
    4. echo "偶数"
    5. else
    6. echo "奇数"
    7. fi #与if成对存在

    十、if分支语句

    a.条件语句
    1 第一种:
    2 if command ; then
    3 ... 语句列表
    4 fi
    5 第二种:
    6 if command ; then
    7 ... 语句列表
    8 else
    9 ... 语句列表
    10 fi
    11 第三种:
    12 if command ; then
    13 ... 语句列表
    14 elif command ; then
    15 ... 语句列表
    16 else
    17 ... 语句列表
    18 fi
    1. #!/bin/bash
    2. # read var
    3. # if [ $var = "hello" ] ; then
    4. # echo "yes"
    5. # elif [ $var = "other" ] ; then
    6. # echo "other"
    7. # else
    8. # echo "no"
    9. # fi

    练习6:从键盘上获取两个整数,比较大小,输出最大值
    练习7:判断一个文件是否存在,若存在则打印文件的内容,不存在则输出字符串报错
    练习8:用shell编写脚本程序:读取变量dir,如果该变量代表的值是目录,则切换到该目录下,
    并在该目录下创建空文件file.txt,将“hello world ”写到该文件中
    如果该目录不存在则创建该目录并切换过去,并显示当前绝对路径
    1. #!/bin/bash
    2. #从键盘上获取两个整数,比较大小,输出最大值
    3. # read -p "inputdata:" val1 val2
    4. # if [ $val1 > $val2 ] ; then
    5. # echo "max:$val1"
    6. # else
    7. # echo "max:$val2"
    8. # fi
    9. #判断一个文件是否存在,若存在则打印文件的内容,不存在则输出字符串报错
    10. # read var
    11. # if test -f $var ; then
    12. # echo "is a file"
    13. # read val<$var
    14. # echo "file txt:$val"
    15. # else
    16. # echo "not a file"
    17. # echo "`$var`"
    18. # fi
    19. #用shell编写脚本程序:读取变量dir,如果该变量代表的值是目录,则切换到该目录下,
    20. # 并在该目录下创建空文件file.txt,将“hello world ”写到该文件中
    21. # 如果该目录不存在则创建该目录并切换过去,并显示当前绝对路径
    22. # read dir
    23. # if test -d $dir ; then
    24. # `cd $dir`
    25. # `touch $dir/file.txt`
    26. # str="hello world"
    27. # `echo $str>$dir/file.txt`
    28. # else
    29. # `mkdir $dir`
    30. # `cd $dir`
    31. # echo "当前路径:`pwd`"
    32. # fi

    十一、多路分支语句

    1、格式

    1 case expression in
    2 pattern1 )
    3 ... 语句列表
    4 ;; // 作用类似与 C 语言的 break , 这里 ;; 不能省
    5 pattern2 )
    6 .... 语句列表
    7 ;;
    8 patternn )
    9 .... 语句列表
    10 ;;
    11 * ) --- 其他值
    12 .... 语句列表
    13 ;;
    14 esac

    2、总结

    1)expression 既可以是一个变量、一个数字、一个字符串,还可以是一个数学计算表达式,或者是命令的执行结果,只要能够得到 expression 的值就可以。
    2)pattern 可以是一个数字、一个字符串,甚至是一个简单的正则表达式。
    3)case语句真正的功能强大之处在于它可以使用模式而不是固定的字符串匹配。一个模式是由一串正规字符和特殊的通配符组成的字符串,该模式可以用正则表达式。

    3、例子

    例子1:
    执行程序后,从键盘中获取一个值
    如果该值为1,则打印one
    如果该值为2,则打印two
    如果该值其他值,则打印error
    1 read val
    2 case $val in
    3 1 )
    4 echo "one"
    5 ;;
    6 2 )
    7 echo "two" 例子2:
    8 ;;
    9 * )
    10 echo "error"
    11 ;;
    12 esac

     例子2:

     

    练习8:
    假设有一个文件test.txt,内容为10,要求写一个脚本,判断文件的内容 cat $1
    内容是10,打印large
    内容是5,打印middle
    内容是1,打印small
    其他值,打印other
    执行脚本时 ./xxxx.sh test.txt ---> 如果参数不为1,则打印input arg error!
    1. if [ $# != 1 ] ; then
    2. echo "input arg error!"
    3. fi
    4. case `cat $1` in
    5. 10)
    6. echo "large"
    7. ;;
    8. 5)
    9. echo "middle"
    10. ;;
    11. 1)
    12. echo "small"
    13. ;;
    14. *)
    15. echo "other" #类似于C语言里面的default
    16. ;;
    17. esac

    十二、循环语句

    1、for循环

    格式:
    1 for 变量名 in 单词表
    2 do
    3 语句列表
    4 done

    比如:

    1 for val int 1 2 3 4 5
    2 do
    3 echo $val
    4 done

    执行结果:

    1 china @ubuntu : ~/ shelldir$ chmod 777 for . sh
    2 china @ubuntu : ~/ shelldir$ . / for . sh
    3 1
    4 2
    5 3
    6 4
    7 5
    1 for val int $ *
    2 do
    3 echo $val
    4 done

    执行结果:

    1 china @ubuntu : ~/ shelldir$ . / for . sh 1 2 3 4 5 6
    2 1
    3 2
    4 3
    5 4
    6 5
    7 6

    ===>for也可以写成C风格相同的for循环

    for((i=1; i<=5; i++ ))

    do
            echo " $i "
    done

     

    //双圆括号(())使得shell程序中可以使用C语言的for风格
    练习:写一个脚本,求1到100的和
    1. #求1100的和
    2. val=0
    3. for (( i=1; i<=100 ;i++));
    4. do
    5. val=`expr $i + $val`
    6. done
    7. echo "val:$val"

    2、while循环

    格式:
    1 while 命令或表达式
    2 do
    3 语句列表
    4 done
    5 ===> 也可以用 C 语言的 while 风格
    6 while (())
    7 do
    8 语句列表
    9 done

     比如:从键盘上获取一个最小值和最大值,打印他们两个之间的所有取值

    1 read - p "min:" min
    2 read - p "max:" max
    3 while test $ min - le $ max
    4 do
    5 echo "$min"
    6 min = `expr $ min + 1 `
    7 done

    练习:写一个脚本,求1到100的和 

    1. # 求1100的和
    2. # val=0
    3. # i=1
    4. # while (($i <=100))
    5. # do
    6. # val=`expr $val + $i`
    7. # i=`expr $i + 1`
    8. # done
    9. # echo "val:$val"

    3、 until

    格式:
    1 until 命令或表达式
    2 do
    3 done
    until与while功能相似,所不同的是只有当测试的命令或表达式的值为假时,才执行循环体中的命令列表。若条件成立则退出循环。这一点与while恰好相反。

    4、break 和 continue

    break n 跳出 n 层循环
    continue n 跳到 n 层循环语句的下一轮循环去
    break continue 后面不加 n, 则和 C 语言里面的含义一样
    练习:写一个脚本,实现可以不断地从键盘获取数据
    如果获取的数据为 "exit" ,则退出
    如果获取的数据小于100,则打印值
    如果获取的数据是其他的,则打印 "other"
    1. #!/bin/bash
    2. while read -p "请输入:" var
    3. do
    4. if test $var = "exit" ; then
    5. break
    6. elif test $var -lt 100 ; then
    7. echo "$var"
    8. continue
    9. else
    10. echo "other"
    11. fi
    12. done

    十三、函数

    格式:
    1 function_name ()
    2 {
    3 ... 命令列表
    4 echo $ 1 $ 2 $ 3
    5 return 123
    6 }
    function_name:你自定义的函数名,名字的取法与C语言类似
    函数的调用
    function_name arg1 arg2 arg3
    在函数内部 arg1==>$1 arg2==>$2 arg3==>$3
    获取函数的返回值
    1 function_name arg1 arg2 arg3
    2 ret = $ ?
    注意:
    1、函数的返回值的大小不超过一个字节
    2、SHELL没有变量作用域,如果出现重复变量名会认为是同一个。
    比如:
    1 get_sum ()
    2 {
    3 return `expr $ 1 + $ 2 `
    4 }
    5 read var1 ; read var2
    6 get_sum $var1 $var2
    7 echo $ ?
    练习:编写一个脚本,封装一个函数实现比较两个数的最大值并且返回
    练习:编写一个脚本,实现一个函数求a+...+b的和 a:5 b=10
    1. # get_max()
    2. # {
    3. # if test $1 -gt $2 ; then
    4. # return $1
    5. # else
    6. # return $2
    7. # fi
    8. # }
    9. # read -p "inputdata:" var1 var2
    10. # get_max $var1 $var2
    11. # echo "max:$?"
    1. get_sum()
    2. {
    3. sum=0
    4. a=$1
    5. b=$2
    6. if test $a -ge $b ; then
    7. while test $b -le $a
    8. do
    9. sum=`expr $sum + $b`
    10. b=`expr $b + 1`
    11. done
    12. else
    13. while test $a -le $b
    14. do
    15. sum=`expr $sum + $a`
    16. a=`expr $a + 1`
    17. done
    18. fi
    19. return $sum
    20. }
    21. read -p "input 2 number:" val1 val2
    22. get_sum $val1 $val2
    23. echo "from $val1 to $val2 sum:$?"

     

     

     

     

     

  • 相关阅读:
    Spring整合MyBatis、Spring整合JUnit4(Spring纯注解开发完结篇)
    安全运营中心自动化究竟是好还是坏
    iOS开发者是钻研SwiftUI还是尝试接触Flutter好呢?
    uni-app 高度自适应
    2021年IB各科7分率
    用支持向量机进行光学符号识别
    【AI】Deepstream入门(2)Ubuntu20.04安装Deepstream
    Jetpack架构组件_1.基本知识
    DPDK-A1:Centos配置MLX5驱动
    import javax.validation* 对输入时间 Date 进行校验的注解
  • 原文地址:https://blog.csdn.net/weixin_48102054/article/details/127738000