• Linux Shell脚本


    shell是用C语言编写的程序,为用户与Linux之间的桥梁。但是,本篇文章中的shell是指shell脚本语言。

    话不多说,先上个例子。脚本 test.sh 如下:

    #!/bin/bash
    #打印出Hello,World
    echo "Hello,World"

    说明1. #! 是一个约定的标记,用来告诉系统该脚本需要什么解释器来执行,如 #!/bin/sh   #!/bin/bash

    说明2. 第二行是注释,shell中的注释使用 #

    执行shell脚本的两种方法:

      1. 可执行程序

        chmod  +x  ./test.sh  #使脚本具有执行权限

        ./test.sh  #执行脚本

      2. 作为解释器参数执行

        /bin/sh  test.sh  (可以简写为 sh  test.sh)

    二、shell变量

    2.1 shell变量命名规则

      1)只能用英文字母、数字和下划线,且首字母不能以数字开头;

      2)中间不能有空格、标点符号等其他符号;

      3)不能使用bash的保留关键字

    2.2 shell变量定义和使用

      定义语法:  varname=值

        注意: =号前后不能有空格

      使用变量语法: $varname

        也可以使用 ${varname}  , {} 为可选项,界定变量名边界

    2.3 只读变量

      使用 readonly 命令修饰的变量,值不可变,称只读变量。如

        readonly  varname="test.sh"

    2.4 删除变量

      使用 unset 命令可以删除非只读变量。如

        varname=11

        unset  varname

    2.5 shell中同时存在三种变量

      1) 局部变量

      2)环境变量

      3)shell变量

    三、shell中数据结构

    3.1 字符串

      1)可以使用单引号、双引号,也可以不使用引号

        单引号:1.包含的字符串会原样输出;2.包含的字符串不能出现单独一个单引号

        双引号:1.包含的字符串可以出现变量;2.可以有转义符

      2)定义一个字符串: str=abcd

      3)获取字符串的长度:  ${#str}

      4)提取子字符串: ${#str:first:length}   #从first位置起截取length长度的字符串

      5)查找子字符串: `expr  index  "$str"  io`  #使用反引号`

    3.2 shell数组

      shell只支持一维数组,并且不限定数组的大小,数组的下标是从0开始的,下标可以是整数或算术表达式,其值应该大于或者等于0.

      1)数组的定义: shell中使用括号()定义数组,元素之间用“空格”分隔,语法如下

        array_name=(value0  value1  value2 .........  valueN)

        也可以使用下标来定义:  array_name[下标]=value

      2)读取数组 语法:   ${array_name[下标]}    #下标为@或者*表示所有元素

      3)获取数组长度: 与获取字符串长度的方法相同

        获取数组元素个数:  ${#array_name[@]}  或者  ${#array_name[*]}

        获取单个元素的长度: ${#array_name[下标]}

    四、shell注释

      单行注释:  #

      多行注释:  :<<EOF

              .........

              .........

            EOF

          或者

           :<<!

            ...............

            ...............

          !

    五、shell基本运算符

      包括 算数运算符、关系运算符、布尔运算符、字符串运算符、文件测试运算符。

    5.1 算数运算符

      原生Bash不支持简单的数字运算,但可以使用其他命令实现,如awk和expr,其中expr最常用

      例如: val=`expr 2 + 2`

        注意1:表达式和运算符之间必须有空格;

        注意2:必须使用``(反引号)包含

      算数运算符及其说明和举例

        + : 加法, `expr $a + $b`

        - : 减法

        * : 乘法

        / : 除法

        % : 取余

        = : 赋值, a=$b

        == : 相等, [$a == $b]

        != : 不相等

    5.2 关系运算符

      只支持数字和值为数字的字符串

      关系运算符及其说明和举例

        -eq : 是否相等, [$a -eq $b]

        -nq : 是否不相等, [$a -nq $b]

        -gt : 大于, [$a -gt $b]

        -lt : 小于, [$a -lt $b]

        -ge : 大于等于, [$a -ge $b]

        -le : 小于等于, [$a -le $b]

    5.3 布尔运算符

      布尔运算符及其说明和举例

        ! : 非, [!false]

        -o : 或,[$a -lt 20 -o $b -gt 100]

        -a : 与,[$a -lt 20 -a $b -gt 100]

    5.4 逻辑运算符

      逻辑运算符及其说明和举例

        && : 逻辑的AND, [[$a -lt 20 && $b -gt 100]]

        || : 逻辑的OR,[[$a -lt 20 || $b -gt 100]]

    5.5 字符串运算符

      字符串运算符及其说明和举例

        = : 是否相等,相等为true, [ $a = $b ]

        != : 是否不相等,不相等为true, [ $a != $b ]

        -z : 长度是否为0,0为true, [ -z $a ]

        -n : 长度是否为0,不为0为true, [ -n $a ]

            : 是否为空,不为空返回true, [ $a ]

    5.6 文件测试运算符

      用于检测unix文件的各种属性

      文件测试运算符及其说明和举例

        -b  file : 检测文件是否是块设备文件,是返回true, [ -b file ]

        -c  file : 是否是字符设备文件,是返回true

        -d  file : 是否是目录,是返回true

        -f  file : 是否是普通文件,是返回true

        -g  file : 是否设置了SGID位,是返回true

        -k  file : 是否设置了粘着位(sticky Bit),是返回true

        -p  file : 是否是有名管道,是返回true

        -u  file : 是否设置了SUID位,是返回true

        -r  file : 文件是否可读,是返回true

        -w  file : 文件是否可写,是返回true

        -x  file : 文件是否可执行,是返回true

        -s  file : 文件是否为空,不为空返回true

        -e  file : 文件(目录)是否存在,是返回true

    5.7 test命令

      用于检查某个条件是否成立,可以进行数值、字符和文件三个方面的测试。与上面的“关系运算符”、“字符串运算符”、“文件测试运算符”相同,只是写法上不同。

      test命令写法如下:

        test  ${num1}  -eq  ${num2}

    六、shell打印命令

      shell打印命令有 echo 和 printf

    6.1 shell  echo命令

      用于字符串的输出,格式 : echo str

      显示普通字符串: echo "It is a test"

      显示转移字符: echo ""It is a test""

      显示变量: echo  $str

      开启转义: echo  -e  "OK! "  #换行

            echo  -e  "OK! c" #不换行

      单引号'' 与 双引号"" 的区别

        单引号:原样输出;双引号:变量、转义符等均生效。

      显示命令执行结果: echo  `date` #注意是反引号

      echo总结

        名称 | 能否引用变量 | 能否引用转义符 | 能否引用文本格式符(换行、制表等符号)

        单引号 | 否 | 否 | 否

        双引号 | 能 | 能 | 能

        无引号 | 能 | 能 | 否

    6.2 printf 命令

      相较于 echo ,printf 具有很好的移植性,但是printf不会自动添加换行符,需要手动添加

      printf命令的语法: printf  format-string  [arguments ......]

        说明1: format-string  格式控制字符串

        说明2: arguments 参数列表

      例如:  printf  "%-10s  %-8s  %-4s "  姓名  性别  体重kg

      printf格式替换符: %d   %s   %c   %f

        d : Decimal 十进制整数

        s : String 字符串

        c : char 字符

        f : Float 浮点数

      printf的转义序列:

        a : 警告字符;

         : 后退

        c : 

        f : 换页

         : 换行

         : 回车

         : 水平制表符

        v : 垂直制表符

        \ : 一个字面上的反斜杠字符

        ddd : 表示 1 到 3 位数八进制值的字符,仅在格式字符串中有效

        ddd : 表示 1 到 3 位的八进制值字符

    七、read 命令

      read命令从标准输入中读取一行,并把输入行的每个字段的值指定给shell变量。read命令一个一个词组地接收输入的参数,之间用空格分隔,输入的词大于需要参数的个数,则最后多余的会成一个整体

      read 参数说明:

        -p : 输入提示文字

        -n : 输入字符长度限制

        -t : 输入限时

        -s : 隐藏输入内容

    八、shell流程控制

      首先声明一点,shell控制流中不能为空。

      8.1 if

        格式:

          if  condition

          then

            command1

            ...........

            commandn

          fi

      8.2 if else

        格式:

          if  condition

          then

            command1

            ..........

            commandn

          else

            command1

            ..........

            commandn

          fi

        8.3 if else-if else

          格式:

            if  condition

            then

              command1

              .........

              commandn

            elif  condition

            then

              command1

              .........

              commandn

            .........

            .........

            else

              command1

              ..........

              commandn

            fi

      8.4 for循环

        格式:

          for  var  in  列表

          do

            command1

            ..........

            commandn

          done

        或者

          for((assignment; condition; next))

          do

            command1

            .........

            commandn

          done

      8.5 while结构

        格式:

          while  condition

          do

            command1

            ...........

            commadn

          done

      8.6 无限循环

        格式:

          while :

          do

            command1

            ..........

            commandn

          done

        或者

          while  true

          do

            command1

            ........

            commandn

          done

        或者

          for((;;))

          do

            command1

            ..........

            commandn

          done

      8.7 until循环

        until循环只有条件为fasle才执行,条件为true则终止执行。与while刚好相反。

        格式:

          until  condition

          do

            command1

            ............

            commandn

          done

      8.8 shell中的break 和 continue

        用于退出循环,用法跟java语言中相同。

      8.9 case多选择语句

        匹配一个值与一个模式,如果匹配成功,执行相匹配的命令

        格式:

          case  值  in

          模式1)

            command1

            ...........

            commandn

          模式2)

            command1

            ...........

            commandn

          ..............

          ..............

          模式n)

            command1

            ...........

            commandn

          *)

            command1

            ...........

            commandn

          esac

    九、shell函数

      格式:

        [function]  funname[()]

        {

          astion;

          [return int;]

        }

      注意:1. 调用函数时直接使用函数名 funname;2. return后跟数值;如果没有显示return则将最后一条命令的运行结果作为返回值;3. 调用函数之后,用 $? 来获取函数返回值;4. 函数调用必须在使用后;5. 可以使用函数传参,函数中获取参数的方式为 $n (n >= 1,且n < 10时可以省去{})。

    十、shell传递参数

      执行shell脚本或者调用shell函数时,可以向脚本或者函数传递参数。

      在脚本中使用 $n 获取参数,$n 表示第n个参数,其中 n 为大于0的整数。

      10.1 特殊参数

        $0 : 所执行脚本的文件名;

        $# : 传递到脚本的参数个数;

        $* : 以一个单字符串显示所有向脚本传递的参数;

        $$ : 脚本运行的当前进程ID号;

        $! : 后台运行的最后一个进程的ID号;

        $@ : 与 $* 相同,但是使用时加引号,并在引号中返回每个参数;

        $- : 显示shell使用的当前选项;

        $? : 显示最后命令的退出状态,0表示正确退出,其他值表示错误。

      10.2 $* 与 $@ 区别

        相同点: 都是引用所有参数;

        不同点: 只有在双引号中体现出来, * 号: "1 2 3", @: "1" "2" "3"

    十一、shell输入/输出重定向

      标准输入/标准输出 : 默认输入/输出为终端

      重定向命令列表如下:

        命令  |  说明

          command  >  filename   |   将输出重定向到filename

          command  < filename    |    将输入重定向到fielname

          command  >>  filename   |    将输出以追加的方式重定向到filename

          n  >  filename   |    将文件描述符为n的文件重定向到filename

          n  >>   filename   | 将文件描述符为n的文件以追加的方式重定向到filename   

          n   >&  m   |   将输出文件m 和 n合并

          n  <&  m    |    将输入文件m 和 n合并

          << tag     |    将开始标记tag和结束标记tag之间的内容作为输入

          n的取值:  0 (标准输入);  1 (标准输出);  2 (标准错误输出)

      11.1 Here Document

        shell中的一种特殊的重定向方式,用来将输入重定向到一个交互式shell脚本或程序

        格式:

          command  <<  delimiter

            document

          delimiter

        作用是将两个delimiter之间的内容document作为输入传递给command

        注意:结尾的delimiter前后不能有任意的其他字符

        例如:

          cat  <<  EOF

            "It is a test"

          EOF

      11.2 /dev/null 文件

        写入该文件中内容会被丢弃;从该文件中也读不出任何内容。

    十二、shell文件包含

      shell可以包含外部的脚本。

      格式:

        .  filename   #注意点号(.)和文件名中间有一个空格

      或者

        source  filename

      注意:被包含的文件不需要可执行权限。

  • 相关阅读:
    java多线程
    golang编码转换
    golang csv,xls,xlsx
    golang 资源
    electron安装
    Ubuntu系统下面软件安装更新命令
    golang代码执行顺序
    datatables使用
    Echarts柱形图颜色设置
    golang chan 超时
  • 原文地址:https://www.cnblogs.com/aston/p/9960518.html
Copyright © 2020-2023  润新知