• Shell编程


    第一个shell脚本:
    #!/bin/bash
    echo "hello world"
    运行shell脚本的三种方法:
    • 方法1:chmod +x ./test.sh;./test.sh -作为可执行程序,需要执行权限

    • 方法2:source test.sh -在当前 bash 环境下读取并执行文件中的命令,无需执行权限。或 . test.sh

    • 方法3:bash test.sh -打开一个子shell来执行文件中的命令,无需执行权限

    在shell语法中执行linux命令:
    • 方法1:echo `pwd`

    • 方法2:echo $(pwd)

    变量使用:
    • 变量定义:val=jack 等价于 val='jack' 等价于 val="jack";=两边不允许有空格

    • 变量引用:echo $val 等价于 echo ${val} 推荐加{} 有助于识别变量边界

    • 只读变量:readonly val

    • 删除变量:unset val

    • 字符串拼接:echo 'hello '${val}" world"

    • 字符串切片:echo ${val:1:3}

    • 字符串截取:路径处理时常用

      # 字符串截取(界定字符本身也会被删除)
      str="www.runoob.com/linux/linux-shell-variable.html"
      echo "str   : ${str}"
      echo "str#*/   : ${str#*/}"   # 从 字符串开头 删除到 左数第一个'/'
      echo "str##*/   : ${str##*/}"  # 从 字符串开头 删除到 左数最后一个'/'
      echo "str%/*   : ${str%/*}"   # 从 字符串末尾 删除到 右数第一个'/'
      echo "str%%/*   : ${str%%/*}"  # 从 字符串末尾 删除到 右数最后一个'/'
      # 输出结果
      str     : www.runoob.com/linux/linux-shell-variable.html
      str#*/ : linux/linux-shell-variable.html
      str##*/ : linux-shell-variable.html
      str%/* : www.runoob.com/linux
      str%%/* : www.runoob.com
    数组使用:
    • 数组定义:array_name=(value0 value1 value2 value3)

    • 数组元素值获取:valuen=${array_name[n]}

    • 获取数组所有元素:echo ${array_name[@]} 等价于 echo ${array_name[*]}

    • 获取数组元素个数:length=${#array_name[*]}

      #!/bin/bash
      my_arry=(a b "c","d" abc)
      # 循环输出数组
      for i in ${my_arry[@]};
      do
       echo $i
      done
      # while循环: let j++自增; []左右均有空格
      j=0
      while [ $j -lt ${#my_arry[@]} ]
      do
       echo ${my_arry[$j]}
      let j++
      done
    注解:单行使用#
    脚本参数传递:
    #!/bin/bash
    # 获取脚本参数个数
    echo $#
    # 获取某个参数的值: $1、$2、... $n
    echo $1
    # $*获取所有参数:但是所有参数拼成的单个字符串
    for i in "$*";do
    echo $i
    done
    # $@获取所有参数:传递多个参数非拼合
    for i in $@;do
    echo $i
    done
    # 显示上个命令的执行状态:0表示没有错误,其他值表示有错误; 或函数的返回值
    echo $?

    本传递的参数中如果包含空格,应该使用单引号或者双引号将该参数括起来,以便于脚本将这个参数作为整体来接收.

    表达式计算:
    • expr 5 + 6:运算间要有空格 等价于$[1+2]

    • r=$[a+b]:无需空格

    • 对于用反引号括起的表达式需要赋值给变量或直接echo才能使用:val=`expr 5 + 6`

    • val=$((1+2)):无需空格

    • val=$(expr 5 + 6):相比第3种,更推荐这种

    键盘输入信息:read -p "input a val:" a 获取键盘输入赋值给a,-p设置提示信息
    算术运算符:
    • '*':使用特殊运算符要转义

    • ==、!=:方括号之间要有空格

      if [ $a != $b ]
      then
        echo "a 不等于 b"
      fi
    关系运算符:只支持数字不支持非数字的字符串
    运算符说明举例
    -eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。
    -ne 检测两个数是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
    -gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
    -lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
    -ge 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
    -le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。
    a=10
    b=20
    if [ $a -eq $b ]
    then
      echo "$a -eq $b : a 等于 b"
    else
      echo "$a -eq $b: a 不等于 b"
    布尔运算符:
    运算符说明举例
    ! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
    -o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
    -a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。
    逻辑运算符: 作用上与布尔运算符一样,但写法上不同,逻辑运算符用在[[]]中,用在[]中会报错应用布尔运算符替换
    运算符说明举例
    && 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
    || 逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true
    1、进行数值比较时,可以使用 [ expression1 OPexpression2 ],OP 可以为 -gt、-lt、-ge、-le、-eq、-ne 也可以使用 ((expression1 OP expression2)),OP 可以为 >、<、>=、<=、==、!=。这几个关系运算符都是测试整数表达式 expression1 和 expression2 之间的大小关系。
    2、 >、<、==、!= 也可以进行字符串比较。
    3、进行字符串比较时,== 可以使用 = 替代。
    4、 == 和 !=进行字符串比较时,可以使用 [ string1 OP string2 ] 或者 [[ string1 OP string2 ]] 的形式。
    5、 > 和 < 进行字符串比较时,需要使用[[ string1 OP string2 ]] 或者 [ string1 OP string2 ]。也就是使用 [] 时,> 和 < 需要使用反斜线转义。
    [] 表达式
    注意:在 [] 表达式中,常见的 >, < 需要加转义字符,表示字符串大小比较,以 acill 码位置作为比较。不直接支持 >, < 运算符,还有逻辑运算符 || 、&& ,它需要用 -a[and] –o[or] 表示。
    [[ ]] 表达式
    注意:[[]] 运算符只是 [] 运算符的扩充。能够支持 >, < 符号运算不需要转义符,它还是以字符串比较大小。里面支持逻辑运算符:|| && ,不再使用 -a -o。
    判断字符串是否为空:
    • -n:字符串长度不为0返回true(对于未定义变量和""空串均为false). if [ -n "$a" ] 或 if [[ -n $a ]] 禁用 if [ -n $a ]. 建议使用双括号

    • -z:字符串长度为0返回true(对于未定义变量和""空串均为true) . if [ -z $a ] 或 if [[ -z $a ]] 推荐后者

    • $:直接使用变量判断长度不为0返回true. 等价于 -n. if [ $a ] 或 if [[ $a ]] 推荐后者

    • 貌似无法区分变量是否存在与变量是否为空字符串,对于未定义的变量默认值为空字符串

    文件测试运算符:建议if判断均使用双括号
    • -d:判断是否为目录,若是为true

    • -f:判断是否为文件,若是为true

    • -r/-w/-x:判断文件是否可读可写可执行,若是为true

    • -s:判断文件是否非空(大小>0)

    • -e:判断文件/目录是否存在,若存在为true

    echo输出命令:自动在末尾添加换行符
    • echo -e "OK! ":开启转义(默认原样输出).

    • echo -e "OK! c"; echo "jack":c不换行

    • 单引号:任何字符原样输出(换行符、tab符等文本格式符除外),引用变量无效,引用转义字符无效(eg:"原样输出)

    • 反引号``:将一个命令的标准输出插在原命令行中. 或者$(...)结构括起来,其中,$(...)格式受到POSIX标准支持,也利于嵌套。 

    • 双引号:能引用变量,能引用转义符,能引用文本格式符

    •  能否引用变量能否引用转义符能否引用文本格式符(如:换行符、制表符)
      单引号
      双引号
      无引号
    printf格式化输出:
    • 默认不会在末尾添加换行符,以空格分隔参数

    • printf "%-10s %-8s %-4.2f " 郭靖 男 66.1234

    • %s %c %d %f都是格式替代符

    • %-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。

    • %-4.2f 指格式化为小数,其中.2指保留2位小数。

    read输入命令:
    • read 命令一个一个词组地接收输入的参数,每个词组需要使用空格进行分隔;如果输入的词组个数大于需要的参数个数,则多出的词组将被作为整体为最后一个参数接收。

    • -p 输入提示文字;-n 输入字符长度限制(达到6位,自动结束);-t 输入限;-s 隐藏输入内容

    重定向输入输出:
    > 重定向输出到某个位置,替换原有文件的所有内容。
    >> 重定向追加到某个位置,在原有文件的末尾添加内容。
    < 重定向输入某个位置文件。
    2> 重定向错误输出。
    2>> 重定向错误追加输出到文件末尾。
    &> 混合输出错误的和正确的都输出。
    command > file 2>&1:将 stdout 和 stderr 合并后重定向到 file

    一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
    标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
    标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
    标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
    默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。

    放在>后面的&,表示重定向的目标不是一个文件,而是一个文件描述符.换言之 2>1 代表将stderr重定向到当前路径下文件名为1的regular file中,而2>&1代表将stderr重定向到文件描述符为1的文件(即/dev/stdout)中,这个文件就是stdout在file system中的映射.而&>file是一种特殊的用法,也可以写成>&file,二者的意思完全相同,都等价于 >file 2>&1

    如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:command > /dev/null
    /dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。如果希望屏蔽 stdout 和 stderr,可以这样写:
    command > /dev/null 2>&1
    命令说明
    command > file 将输出重定向到 file。
    command < file 将输入重定向到 file。
    command >> file 将输出以追加的方式重定向到 file。
    n > file 将文件描述符为 n (0/1/2)的文件重定向到 file。
    n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。
    n >& m 将输出文件 m 和 n 合并。
    n <& m 将输入文件 m 和 n 合并。
    << tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。
    test命令:if test $val1 == $val2 等价于 if [ $val1 == $val2 ]
    shell条件判断除空串和未定义变量为false,其余均为true(包括零)

    shell 语言中 0 代表 true,0 以外的值代表 false

    流程控制:
    a=10
    b=20
    if [ $a == $b ]
    then
      echo "a 等于 b"
    elif [ $a -gt $b ]
    then
      echo "a 大于 b"
    elif [ $a -lt $b ]
    then
      echo "a 小于 b"
    else
      echo "没有符合的条件"
    fi
    # 写成一行
    if [ $a == $b ]; then echo "a 等于 b"; else echo "a 不等于 b"; fi

    for循环:

    for loop in 1 2 3 4 5
    do
       echo "The value is: $loop"
    done
    # 写成一行
    for var in item1 item2 ... itemN; do command1; command2… done;
    # 写法2:
    for((assignment;condition:next));do
      command_1;
      command_2;
      commond_..;
    done;
    for((i=1;i<=5;i++));do
       echo "这是第 $i 次调用";
    done;
    # 通常情况下 shell 变量调用需要加 $,但是 for 的 (()) 中不需要

    while循环:

    int=1
    while(( $int<=5 )) 等价于  while [ $int -le 5 ]
    do
       echo $int
      let int++
    done
    # 从键盘读取输入知道ctrl+d终止
    while read FILM
    do
       echo "是的!$FILM 是一个好网站"
    done

    case:

    case 值 in
    模式1)
      command1
      command2
      command3
      ;;
    模式2)
      command1
      command2
      command3
      ;;
    *)
      command1
      command2
      command3
      ;;
    esac
    # break或continue的使用
    while :
    do
       echo -n "输入 1 到 5 之间的数字:"
      read aNum
      case $aNum in
           1|2|3|4|5) echo "你输入的数字为 $aNum!"
          ;;
          *) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
              break # 或continue
               echo "hah"
          ;;
       esac
    done
    函数:
    [ function ] funname [()]
    {
      action;
      [return int;]
    }
    1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
    2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255
    --- 示例1:
    funWithReturn(){
       echo "这个函数会对输入的两个数字进行相加运算..."
       echo "输入第一个数字: "
      read aNum
       echo "输入第二个数字: "
      read anotherNum
       echo "两个数字分别为 $aNum$anotherNum !"
      return $(($aNum+$anotherNum))
    }
    funWithReturn
    echo "输入的两个数字之和为 $? !"
    注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。

    --- 函数参数:
    funWithParam(){
       echo "第一个参数为 $1 !"
       echo "第二个参数为 $2 !"
       echo "第十个参数为 $10 !"
       echo "第十个参数为 ${10} !"
       echo "第十一个参数为 ${11} !"
       echo "参数总数有 $# 个!"
       echo "作为一个字符串输出所有参数 $* !"
    }
    funWithParam 1 2 3 4 5 6 7 8 9 34 73
    注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
    --- 0为true,非0均为false
    function demoFun1(){
      return 0
    }
    function demoFun2(){
      return 12
    }

    if demoFun1
    then
       echo true # true
    else
       echo false
    fi

    if demoFun2
    then
       echo ture
    else
       echo false # false
    fi
    脚本引用:在脚本中执行其他脚本

    . test1.sh 等价于 source test1.sh

  • 相关阅读:
    C/C++ 读文件
    算法和数据结构 图表示
    protobuf
    C/C++ jsoncpp
    C/C++ C++11作用域枚举
    腾讯云云函数快速入门实践
    Serverless 与 Flask 框架结合进行 Blog 开发
    从企业微信机器人到小爱同学,用 Serverless 实现生活智能化!
    基于 Serverless 与 Websocket 的聊天工具实现
    云函数 SCF 与对象存储实现 WordCount 算法
  • 原文地址:https://www.cnblogs.com/luckyboylch/p/12482129.html
Copyright © 2020-2023  润新知