• shell脚本编程


    默认情况下,echo在每次调用后会添加一个换行符
    双引号"" 双引号允许shell解释字符串中出现的特殊字符
    单引号'' 单引号不会对字符串中出现的特殊字符做任何解释
    echo "hello world! $PATH"
    echo 'hello world! $PATH'
    如果需要打印像$这样的特殊字符,那就不要将其放入双引号中,而是使用单引号,或是在特殊字符之前加上一个反斜线,用来转义
    1.在echo中转义换行符
    默认情况下,echo会在输出文本的尾部追加一个换行符,可以使用-n选项来禁止。
    echo使用转义序列时,需要使用echo -e "包含转义序列的字符串"这种形式
    echo -e "1 2 3"
    2.打印彩色输出
    脚本可以使用转义序列在终端中生成彩色文本,文本颜色是由对应的色彩码来描述的。其中包括:
    重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,洋红=35,青色=36,白色=37
    echo -e "e[1;31m This is red text e[0m"
    其中e[1;31m就是一个转义字符串,可以将颜色设置为红色,e[0m将颜色重新置回。只需要将31替换成想要的色彩码就行了
    对于彩色背景,经常使用的颜色码是:重置=0,黑色=40,红色=41,绿色=42,黄色=43,蓝色=44,洋红=45,青色=46,白色=47
    echo -e "e[1;42m Green Background e[0m"

    假设有一个叫做gedit的应用程序正在运行,我们可以使用pgrep来获得gedit的进程ID
    可以使用等号操作符为变量赋值 varName=value,varName是变量名,value是赋给变量的值。如果value不包含任何空白字符(例如空格),那么就不需要将其放入引号,否则必须使用单引号或双引号。
    注意:var = value不同于var=value。把var=value写成var = value是一个常见的错误。两边没有空格的等号是赋值操作符,加上空格的等号表示的是等量关系测试。
    fruit=apple
    count=5
    echo "we have $count ${fruit}(s)"
    因为shell使用空白字符来分隔单词,所以我们需要加上一对花括号来告诉shell这里的变量名是fruit

    获得字符串的长度:length=${#var} length就是字符串所包含的字符数

    修改bash的提示字符串

      当我们打开终端或者运行shell时,会看到类似于user@hostname:/home/$的提示字符串。不同的GNU/Linux发布版中的提示字符串及颜色各不相同。我们可以利用PS1环境变量来定义主提示字符串。默认的提示字符串是在文件~/.bashrc中的某一行定义的,我们可以修改PS1的值来修改提示字符串

    shell脚本编程基础

    shell编程:过程式、解释执行

    编程语言的基本结构:

      各种系统命令的组合

      数据存储:变量、数组

      表达式:a+b

      语句:if

    shell脚本:

      包含一些命令或声明,并符合一定格式的文本文件

    格式要求:首行shebang机制

      #!/bin/bash

      #!/usr/bin/python

      #!/usr/bin/perl

    shell脚本的用途有:

      自动化常用命令

      执行系统管理和故障排除

      创建简单的应用程序

      处理文本文件

    创建shell脚本

    第一步:使用文本编辑器来创建文件

      第一行必须包括shell声明序列:#!

      #!/bin/bash

      添加注释

      注释以#开头

    第二步:运行脚本

      给与执行权限,在命令行上指定脚本的绝对或相对路径

      直接运行解释器,将脚本作为解释器程序的参数运行

    脚本调试

      1.检测脚本中的语法错误

      bash -n /path/to/script

      2.调试执行

      bash -x /path/to/script


    变量:命令的内存空间

      数据存储方式:  

      字符

      数值:整形,浮点型

    变量命名法则:

      1.不能使用程序中的保留字,例如if,for

      2.只能使用数字、字母及下划线,且不能以数字开头

      3.见名知义

      4.统一命名规则:驼峰命名法(大小写)

    变量类型

      作用

      1:数据存储格式

      2:参与的运算

      3:表示的数据范围

      类型:字符、数值:整型、浮点型

    bash中变量的种类

    根据变量的生效范围等标准划分为下面变量类型:

      局部变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效(echo $变量名)

      环境(全局变量):生效范围为当前shell进程及其子进程(export|declare -x|env 特性:只能向下传递)

      本地变量:

      位置变量:

      特殊变量:$$(表示当前进程的进程编号  pstree -p查看进程树),$?

    局部变量

    变量赋值:name='value'

    可以使用引用value:

      (1)可以是直接字串,name="root"

      (2)变量引用:name="$USER"

      (3)命令引用:name='COMMAND' name=$(COMMAND)

    变量引用:$(name)  $name

      "":弱引用,其中的变量引用会被替换为变量值

      '':强引用,其中的变量引用不会被替换为变量值,而保持原字符串

    删除变量:unset

     环境变量

    变量声明、赋值:

      export name=VALUE

      declare -x name=VALUE

    变量引用:$name

    显示所有环境变量

      env

      printenv

      export

      declare -x

    删除变量

      unset name

     bash内建的环境变量

      PATH

      SHELL

      USER

      UID

      HOME

      PWD

      LANG

      MAIL

      HOSTNAME

      HISTSIZE

    只读和位置变量

      只读变量:只能声明,但不能修改和删除

        声明只读变量:

          readonly name

          declare -r name

        查看只读变量:

          readonly -p

        (umask 666;touch /data/f1):小括号用于一次性任务

        x=1;echo "pid=$$";(echo "subpid=$$";echo "subx=$x";x=2;echo "subx2=$x";);echo x=$x

      位置变量:在脚本中调用通过命令行传递给脚本的参数

        $1,$2,...:对应第1,第2等参数,shift[n]换位置

        $0:命令本身

        $*:传递给脚本的所有参数,全部参数合为一个字符串

        $@:传递给脚本的所有参数,每个参数为独立字符串

        $#:传递给脚本的参数的个数

          $@ $*只有在被双引号包起来的时候才会有差异

        set --清空所有位置变量

        #!/bin/bash

        scp $1 192.168.189.135:/root/bin

      shift[n]的用法

      #!/bin/bash

      echo "1st arg is $1"
      echo "2st arg is $2"
      echo "3st arg is $3"
      shift 2
      echo "1st arg is $1"
      echo "2st arg is $2"
      echo "3st arg is $3"

    退出状态

      进程使用退出状态来报告成功或失败

      0代表成功,1~255表示失败

      $? 变量保存最近的命令退出状态

    退出状态码

      bash自定义退出状态码

      exit [n]:自定义退出状态码

      注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字

      注意:如果未给脚本指定退出状态码,整个脚本的退出状态取决于脚本中执行的最后一条命令的状态码

     基础逻辑运算

    算数运算

      bash中的算数运算:

        +,-,*,/,%取模(取余数)

      实现算数运算:

        1)let var=算数表达式

        2)var=$[算数表达式]

        3)var=$((算数表达式))

        bash有内建的随机数生成器:$RANDOM(0-32767)

          echo $[$RANDOM%50]:0-49之间的随机数

    逻辑判断

        & 并且 and

          0&0=0

          0&1=0

          1&0=0

          1&1=1

        | 或者 or

          0|0=0

          0|1=1

          1|0=1

             1|1=1

        && 短路与     cmd1 && cmd2  如果cmd1为假,则cmd2不需要执行;如果cmd1为真,则cmd2要执行

                  cmd1 && cmd2 || cmd3  cmd1为真,执行cmd2;cmd1为假,执行cmd3

        ||短路或      cmd1||cmd2  如果cmd1为真,则cmd2不需要执行;如果cmd1为假,则cmd2要执行

                  cmd1 || ( cmd2 ;cmd3 )  如果cmd1为true,则执行cmd2和cmd3

                  cmd1 || { cmd2 ; cmd3 }  exit时退出

        XOR 异或

          0^0=0

          0^1=1

          1^0=1

          1^1=0

          两个数互换:let a=a^b;let b=a^b;let a=a^b

         非:!

          !1=0

          !0=1

    条件测试

      判断某需求是否满足,需要由测试机制来实现

        专用的测试表达式需要由测试命令辅助完成测试过程

      评估布尔声明,以便用在条件性执行中

        若真,则返回0

        若假,则返回1

      测试命令:

        test EXPRESSION  help test

        [ EXPRESSION ]

        [[ EXPRESSION ]]

        []和[[]]的区别:

          是否用正则表达式,用正则表达式时,用[[]]

        注意:EXPRESSION前后必须有空白字符

      ()、(())、[]、[[]]、{}的区别:

        []和test命令一样,用变量时建议加双引号引起来

          -a FILE:True if file exists

          -d FILE:True if file is a directory

          -f FILE:True if file exists and is a regular file

          -z STRING:True if string is empty

          -n STRING/STRING:True if string is not empty

        ():用于多个命令组

          false || ( echo cmd1; echo cmd2)

        {} flase || { echo cmd1 ; exit ;}  会退出当前shell

         false || ( echo cmd1 ; exit )  不会退出当前shell,相当于开了一个子shell

      常用逻辑运算符:

        -eq:等于,用于比较数字,即equal

        -ne:不等于,用于比较数字,not equal

        -lt:小于,letter

        -gt:大于,greater

        -le:小于等于

        -ge:大于等于

        EXPR1 -a EXPR2 True if both expr1 and expr2 are true

          [ -r /etc/issue -a -w /etc/passwd ] && echo "read and write"

        EXPR1 -o EXPR2 True if either expr1 or expr2 is true

          [ -r /etc/issue -o -w /etc/passwd ] && echo "read or write"

      bash的字符串测试

        =  是否等于

        >  ascii码是否大于assci码

        <  是否小于

        != 是否不等于

        =~ 左侧字符串是否能被右侧的PATTERN所匹配

          注意:此表达式一般用于[[]]中;扩展的正则表达式

        -z "STRING"  字符串是否为空,空为真,不空为假

        -n "STRING"  字符串是否不空,不空为真,空为假

        注意:用于字符串比较时的用到的操作数都应该使用引号

      使用read命令来接受输入

        -p:指定要显示的提示

        -s:静默输入,一般用于密码

        -n N:指定输入的字符长度N,到达长度N自动退出

        -d '字符':输入结束符时退出

        -t N:timeout为N秒,到了N秒时自动退出

        read从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量

        read -p "input your name:" name

      判断yes no

        ans="yes";[[ $ans =~ ^([Yy]|[Yy][Ee][Ss])$ ]] && echo true

        ans="Yes";[[ $ans =~ ^([Yy]([Ee][Ss])?)$ ]] && echo true

        ans="No";[[ $ans =~ ^([Nn][Oo]?)$ ]] && echo true

     防止扩展

      反斜线()会使随后的字符按原意解释

        echo your cost:$5.00

      加引号来防止扩展

        单引号(')防止所有扩展

        双引号(")也防止所有扩展,但是下列情况除外

        $(美元符号)——变量扩展

        `(反引号)——命令扩展

        (反斜线)——禁止单个字符扩展

        !(叹号)——历史命令扩展

    bash的配置文件

      按生效范围划分,存在两类

        全局配置:

          /etc/profile

          /etc/profile.d/*.sh

          /etc/bashrc

        个人(用户)配置:

          ~/.bash_profile

          ~/.bashrc

    shell登录的两种方式

      交互式登录:

        1)直接通过终端输入账号密码登录

        2)使用"su - username"切换用户

        执行顺序:/etc/profile-->/etc/profile.d/*.sh-->~/.bash_profile-->~/.bashrc-->/etc/bashrc

      非交互式登录:

        1:su username

        2)图形界面下打开的终端

        执行顺序:~/.bashrc-->/etc/bashrc-->/etc/profile.d/*.sh

    .和source与bash的区别

      用bash执行脚本的时候相当于在当前shell的子进程中运行的,不会对当前的环境造成影响

      用source执行脚本的时候相当于在当前shell中运行,会对当前的环境造成影响

    profile类和bashrc类

      按功能划分,存在两类:

        profile类和bashrc类

          profile类:为交互式登录的shell提供配置

          全局:/etc/profile,/etc/profile.d/*.sh

          个人:~/.bash_profile

          功用:

            1)用于定义环境变量

            2)运行命令或脚本

          bashrc类:为非交互式和交互式登录的shell提供配置

          全局:/etc/bashrc

          个人:~/.bashrc

          功用:

            1)定义命令别名和函数

            2)定义本地变量 

    编辑配置文件生效

      修改profile和bashrc文件后需生效

        两种方法:

          1:重新启动shell进程

          2:.或source

    bash退出任务

      保存在~/.bash_logout文件中(用户)

      在退出登录shell时运行


    shell编程进阶

    条件选择if语句

      选择执行:

      注意:if语句可嵌套

      单分支

        if 判断条件;then

          条件为真的分支代码

        fi

      双分支

        if 判断条件;then

          条件为真的分支代码

        else

          条件为假的分支代码

        fi

      多分支

        if 判断条件1;then

          条件为真的分支代码

        elif 判断条件2;then

          条件为真的分支代码

        elif 判断条件3;then

          条件为真的分支代码

        else

          以上条件都为假的分支代码

        fi

     条件判断:case语句

    case支持glob风格的通配符:

      *:任意长度任意字符

      ?:任意单个字符

      []:执行范围内的任意单个字符

      a|b:a或b

    case 变量引用 in

    PART1)

      分支1

      ;;

    PART2)

      分支2

      ;;

    ...

    *)

      默认分支

      ;;(最后这个可以省略)

    esac

    循环

      循环执行

        将某代码段重复运行多次

        重复运行多少次

          循环次数事先已知

          循环次数事先未知

        有进入条件和退出条件

      for,while,until

    for循环(循环次数已知)

      for 变量名 in 列表;do

        循环体

      done

      执行机制:

        依次将列表中的元素赋值给"变量名";每次赋值后即执行一次循环体;直到列表中的元素耗尽,循环结束

    列表生成方式:  

      1直接给出列表,用空格隔开

      2整数列表:

        a){start...end}

        b)$(seq[start[step]]end)

      3返回列表的命令

        $(COMMAND)   或反向单引号     ``

      4使用glob,如:*.sh

      5变量引用

        $@(单个变量),$*(整体的)

    {1..100..3}  以3为步进,取1到100

    seq 1 3 100 以3为步进,取1到100

     {1..100} 1到100

    while循环(循环次数未知)

      while CONDITION;do

        循环体

      done

    CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为"true",则执行下一次循环;直到条件测试状态为"false"终止循环

    因此:CONDITION一般应该有循环控制变量;而此变量的值会在循环体不断的被修正

    进入条件:CONDITION为true

    退出条件:CONDITION为false

    循环控制语句continue

    用于循环体中

    continue[N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层

     #!/bin/bash
    for i in {1..3};do
            for j in {1..10};do
                    if [ $j -eq 5 ];then
                            continue 1
                    fi
                    echo "j=$j"
            done
            echo
    done

    #!/bin/bash
    for i in {1..3};do
            for j in {1..10};do
                    if [ $j -eq 5 ];then
                            continue 2
                    fi
                    echo "j=$j"
            done
            echo
    done

     循环控制语句break

    用于循环体中

    break[N]:提前结束第N层循环,最内层为第一层

    #!/bin/bash
    for i in {1..3};do
            for j in {1..10};do
                    if [ $j -eq 5 ];then
                            break 1
                    fi
                    echo "j=$j"
            done
            echo
    done

    #!/bin/bash
    for i in {1..3};do
            for j in {1..10};do
                    if [ $j -eq 5 ];then
                            break 2
                    fi
                    echo "j=$j"
            done
            echo
    done

    循环控制shift命令

    shift [n]

    用于将参量列表list左移指定次数,缺省为左移一次

    参量列表list一旦被移动,最左端那个参数就从列表中删除。while循环遍历位置参量列表时,常用到shift

     #!/bin/bash
    while [ $# -gt 0 ];do
            echo "$*"
            shift
    done

    创建无限循环

    while true;do

      循环体

    done

    until false;do

      循环体

    done

    while的特殊用法(遍历文件的每一行)

      while read line;do

        循环体

      done < /PATH/FROM/SOMFILE

    依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将值赋给变量line

     对文件逐行操作

    #!/bin/bash
    while read line;do
            uid=`echo $line|cut -d: -f3`
            user=`echo $line|cut -d: -f1`
            if [ $[uid%2] -eq 0 ];then
                    echo "$uid:$user"
            fi
    done </etc/passwd

    对命令结果逐行操作

    #!/bin/bash
    df|while read disk;do
            if echo $disk|grep "^/dev/sd" >/dev/null;then
                    used=`echo $disk | sed -r 's/.* ([[:digit:]]+)%.*/1/'`
                    device=`echo $disk|cut -d" " -f1`
                    [ $used -ge 10 ] && echo "$device will be full,used $used%"
            fi
    done

    特殊用法

    help for

    select循环与菜单

    select variable in list

      do

        循环体命令

      done

    select循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示PS3提示符,等待用户输入

    用户输入菜单列表中的某个数字,执行相应的命令

    用户输入被保存在内置变量REPLY中

    #!/bin/bash
    PS3="Please choose the menu(1-3):"
    select menu in baoyu yanwo renshen;do
            case $menu in
            baoyu)
                    echo "$REPLY:$menu price is 1000"
                    break
                    ;;
            yanwo)
                    echo "$REPLY:$menu price is 2000"
                    break
                    ;;
            renshen)
                    echo "$REPLY:$menu price is 3000"
                    break
                    ;;
            *)
                    echo "the menu is empty"
            esac
    done

    信号捕捉trap

    trap'触发指令'信号

      自定义进程收到系统发出的指定信号后,将执行触发指令,而不会执行原操作

    trap''信号

      忽略信号的操作

    trap'_'信号

      恢复原信号的操作

    trap -p

      列出自定义信号操作

    #!/bin/bash
    trap 'echo press ctrl+c' 2
    trap -p
    for i in {1..10};do
            echo $i
            sleep 0.5
    done
    trap '' 2
    trap -p
    for i in {10..20};do
            echo $i
            sleep 0.5
    done
    trap '-' 2
    trap -p
    for i in {20..30};do
            echo $i
            sleep 0.5
    done

     函数

    函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程

    它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分

    函数和shell程序比较相似,区别在于:

      shell程序在子shell中运行

      而shell函数在当前shell中运行,因此在当前shell中,函数可以对shell中变量进行修改

    定义函数

    函数由两部分组成:函数名和函数体

    help function

    语法一:

      f_name () {

      ...函数体...  

      }

    语法二:

      function f_name {

      ...函数体...

      }

    语法三:

      function f_name () {

      ...函数体...

      }

    函数的定义和使用(函数的优先级比别名和命令高)

      可在交互式环境下定义函数

        declare -f 查看当前shell的所有函数

        unset func 删除函数

        如果函数中有局部变量,如果其名称同本地变量,在函数中定义本地变量的方法

          local NAME=VALUE

        local定义的变量只在函数中有效

        declare -i在函数中相当于local

      可将函数放在脚本文件中作为它的一部分

      可放在只包含函数的单独文件中

    调用:函数只有被调用才会执行

      调用:给定函数名

      函数名出现的地方,会被自动替换为函数代码

    函数的生命周期:被调用时创建,返回时终止

     函数有两种返回值:

    函数的执行结果返回值:

      1.使用echo等命令进行输出

      2.函数体中调用命令的输出结果

    函数的退出状态码:

      1.默认取决于函数中执行的最后一条命令的退出状态码

      2.自定义退出状态码,其格式为:

        return 从函数中返回,用最后状态命令决定返回值

        return 0 无错误返回

        return 1-255 有错误返回

    使用函数文件

    /etc/init.d/functions 定义着许多函数

    可以将经常使用的函数存入函数文件,然后将函数文件载入shell

    source/.   /PATH/functions

    文件名可以任意选取,但最好与相关任务有某种联系

    一旦函数文件载入shell,就可以在命令行或脚本中调用函数。可以使用set/declare -f命令查看所有函数

    若要改动函数,首先用unset命令从shell中删除函数。改动完毕后,再重新载入此文件

    删除shell函数

    现在对函数做一些改动后,需要先删除函数,使其对shell不可用,使用unset命令完成删除函数

    命令格式为:unset function_name

    全局函数(环境函数)——使子进程也可以使用

    声明:export -f function_name

    查看:export -f或declare -xf

    函数参数

    函数可以接受参数:

    传递参数给函数:调用函数时,在函数名后面以空白分隔给定参数列表即可;func1 arg1 arg2...

    在函数体当中,可食用$1,$2,...调用这些参数;还可以使用$@,$*,$#等特殊变量

    数组

    变量:存储单个元素的内存空间

    数组:存储多个元素的连续的内存空间,相当于多个变量的集合

    数组名和索引

      索引:编号从0开始,属于数值索引

      注意:索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引,bash4.0之后的版本支持

      bash的数组支持稀疏格式(索引不连续)

    声明数组:

      declare -a ARRAY_NAME:普通数组可以不声明

      delcare -A ARRAY_NAME:关联索引的数组即关联数组,使用前要声明

      注意:两者不可互相转换

    数组元素的赋值

      1.一次只赋一个元素

      array_name[index]=value

      weekdays[0]="sunday"

      2.一次赋值全部元素

      array_name=("val1""val2""val3"...)

      3.只赋值特定元素

      array_name=([0]="val1" [3]="val2"...)

    显示所有数组:declare -a

    脚本常用命令

    echo

    date

    练习:

    1.编写一个脚本,提示用户输入yes或no,并判断用户输入的是yes还是no,或是其他信息

    #!/bin/bash
    read -p "Please input yes or no:" ANS
    if [ -z "$ANS" ];then
            echo "Do not input empty string"
    else
            case $ANS in
        [Yy]|[Yy][Ee][Ss])
            echo "your answer is yes"
            ;;
        [Nn]|[Nn][Oo])
            echo "your answer is no"
            ;;
        *)
            echo "your answer is wrong"
        esac
    fi

    2.编写一个脚本,提示输入正整数的值,计算1+2+...+n的总和

    #!/bin/bash
    read -p "Please input a number:" num
    declare -i sum=0
    for i in `seq $num`;do
            let sum+=i
    done
    echo "The sum is $sum"

    3.编写一个脚本,打印九九乘法表

     #!/bin/bash
    for i in {1..9};do
            for j in `seq 1 $i`;do
                    result=$[$i*$j]
                    echo -e "${j}x${i}=$result c"
            done
            echo
    done

    4.编写一个脚本,求100以内奇数之和

    #!/bin/bash
    declare -i sum=0
    declare -i a
    for a in {1..100};do
            if [ $[a%2] -eq 1 ];then
                    let sum+=a
            fi
    done   
    echo "The sum is $sum"

    5.编写一个脚本,打印一个矩形

    #!/bin/bash
    read -p "Please input the high:" high
    read -p "Please input the " width
    for i in `seq 1 $high`;do
            for j in `seq 1 $width`;do
                    color=$[RANDOM%7+31]
                    echo -e "33[1;${color}m*33[0mc"
            done
            echo
    done

    6.编写一个脚本,打印出国际象棋盘

    #!/bin/bash
    for i in {1..8};do
            for j in {1..4};do
                    if [ $[i%2] -eq 0 ];then
                            echo -e "33[1;43m  33[0m33[1;41m  33[0mc"
                    else
                            echo -e "33[1;41m  33[0m33[1;43m  33[0mc"
                    fi
            done
            echo
    done

    7.监控httpd服务是否启动,如果暂停服务后立即重启

    #!/bin/bash
    while true;do
            if killall -0 httpd  &>/dev/null;then
                    :
            else
                    systemctl restart httpd &>/dev/null
                    echo at `date "+%F +%T"` restart httpd >> /data/httpd.log
            fi
            sleep 10
    done

    8.编写一个脚本,打印等腰三角形

    9.编写一个脚本,随机生成10以内的数字,实现猜字游戏,提示比较大或者比较小,相等则退出

    #!/bin/bash
    rand=$[RANDOM%11]
    while read -p "Please input a number:" num;do
            [[ $num =~ ^[[:digit:]]+$ ]] || { echo "Please input a 0-10 digit!";continue; }
            if [ $num -gt $rand ];then
                    echo more
            elif [ $num -lt $rand ];then
                    echo litter
            else
                    break
            fi
    done
    echo "You are right"

    10.

  • 相关阅读:
    【EF学习笔记11】----------查询中常用的扩展方法
    .NET 扩展方法
    【EF学习笔记10】----------主从表级联操作
    【EF学习笔记09】----------使用 EntityState 枚举标记实体状态,实现增删改查
    【EF学习笔记08】----------加载关联表的数据 显式加载
    【EF学习笔记07】----------加载关联表的数据 贪婪加载
    【EF学习笔记06】----------加载关联表的数据 延迟加载
    Linux内核ROP姿势详解(二)
    见微知著(三):解析ctf中的pwn--Fastbin和bins的溢出
    见微知著(二):解析ctf中的pwn--怎么利用double free
  • 原文地址:https://www.cnblogs.com/hjmLinux/p/11746677.html
Copyright © 2020-2023  润新知