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! \n"  #换行

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

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

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

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

  echo总结

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

    单引号 | 否 | 否 | 否

    双引号 | 能 | 能 | 能

    无引号 | 能 | 能 | 否

6.2 printf 命令

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

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

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

    说明2: arguments 参数列表

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

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

    d : Decimal 十进制整数

    s : String 字符串

    c : char 字符

    f : Float 浮点数

  printf的转义序列:

    \a : 警告字符;

    \b : 后退

    \c : 

    \f : 换页

    \n : 换行

    \r : 回车

    \t : 水平制表符

    \v : 垂直制表符

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

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

    \0ddd : 表示 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

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

posted @ 2018-11-20 20:51  aston  阅读(205)  评论(0编辑  收藏  举报