嵌入式攻城狮 IV Linux Shell程序设计

一、VIM程序编辑器

  • 1.Vim的三种模式

  • 2.Vim常用按键说明

    • 一般模式

      操作含义
      数字0或功能键Home移动到这一行的最前面字符处
      $或功能键End移动到这一行的最后面字符处
      G移动到这个文件的最后一行
      nGn为数字,移动到这个文件的第n行
      gg移动到这个文件第一行,相当于1G
      /word向下寻找一个名为word的字符串
      ?word向上寻找一个名为word的字符串
      nn为英文按键,重复前一个查找的操作
      NN为英文按键,与n方向相反
      :n1,n2s/word1/word2/gn1与n2为数字,在n1与n2之间查找word1字符串,并替换为word2
      x,Xx==[Del] X==[Backspace]
      dd删除光标所在的一整行
      nddn为数字,删除光标所在的向下n行
      yy复制光标所在的那一行
      nyyn为数字,复制光标所在的向下n行
      p,Pp为将已复制数据在光标下一行粘贴,P为将已复制数据在光标上一行粘贴
      u复原前一个操作(撤销)
      [Ctrl]+r重做上一个操作
      .(小数点)重复前一个操作
    • 编辑模式

      操作含义
      i进入插入模式,从当前光标所在处插入
      a进入插入模式,从当前光标的下一个字符处插入
      [Esc]退出编辑模式,回到一般模式
    • 命令行模式

      操作含义
      :w将编辑的数据写入硬盘文件
      :q离开vim
      :q!不保存离开
      :wq保存后离开
      :set nu显示行号
      :set nonu取消行号
  • 3.块选择 一般模式

    操作含义
    V字符选择或行选择,将光标经过(使用上下左右功能键)的地方反白选择
    [Ctrl]+v块选择,用矩形选择数据
    y将反白的地方复制
    d将反白的地方删除
    p在光标处粘贴
  • 4.多窗口功能 命令行模式下

    • 在命令行模式中输入 :sp{filename} .如果新窗口启动另一文件,输入文件名,否则仅输入 :sp 出现同一个文件的两个窗口。
      [Ctrl]+w+↑ 光标移动到上面窗口
      [Ctrl]+w+↓ 光标移动到下面窗口
      [Ctrl]+w+q 退出,关闭当前窗口
  • 5.Vim环境设置与记录

    • 记录在vim内操作的文件 ~/.viminfo
      vim环境设置参数操作含义
      :set nu/:set nonu设置与取消行号
      :set hlsearch/:set nohlsearch设置与取消高亮查找 hlsearch == high light search
      :set autoindent/:set noautoindent设置与取消自动缩排(回车后,光标在与上一行的第一个非空格符处对齐,而不是出现在行首)
      :set ruler设置右下角状态栏说明
      :set showmode设置左下角状态说明
      :set all显示目前所有环境参数设置值
      :set显示与系统默认值不同的参数
      :syntax on/syntax off语法高亮色
      :set bg=dark/:set bg=light设置背景色
  • 6.vim常用命令示意图


二、认识与学习bash

变量
$ a=Hello
$ echo $a
Hello       #查看变量内容
$ a = 9
a: command not found
$ a= 9
9: command not found    #=两边不能有空格
$ a=9
$ echo $a
9
$ a="ds fd s"
$ echo $a
ds fd s     #字符串有空格须用引号括起 ''或""
$ a=8+9+1+3+4+5+6
$ echo a
a
$ echo $a
8+9+1+3+4+5+6
$ read a
qwert       #用户输入赋值给a 回车结束
$ echo $a
qwert
  1. 引号的使用
    字符串通常被放在 " " 中,以防止变量被空白符号分开,同时允许$扩展。
    variable.sh

    #!/bin/sh
    myvar="Hi there"
    echo $myvar
    echo "$myvar"
    echo '$myvar'
    echo \$myvar
    echo Enter some text
    read myvar
    echo '$myvar' now equals $myvar
    exit 0
    

    执行如下

    $ ./variable.sh
    Hi there
    Hi there
    $myvar
    $myvar
    Enter some text
    Hello World
    $myvar now equals Hello World
    
  2. 环境变量

    环境变量说明
    $HOME当前用户家目录
    $PATH以冒号分隔的用来搜索命令的目录列表
    $PS1命令提示符 $
    $PS2二级提示符 >
    $IFS输入域分隔符 sp tab enter
    $0shell脚本名字
    $#传递给脚本的参数个数
    $$shell脚本的进程号
  3. 参数变量

    参数变量说明
    $1,$2,...脚本程序参数
    $*在一个变量中列出所有参数,各参数之间用 $IFS 中的第一个字符分隔开
    $@$* 的变体,不使用 $IFS 变量,即使 $IFS 为空,参数也不会挨在一起
    $ echo $IFS 
        #这里是一个空格
    $ set foo bar bad
    $ echo "$@"
    foo bar bad
    $ echo "$*"
    foo bar bad
    $ IFS=''
    $ echo "$*"
    foobarbad
    $ echo "$@"
    foo bar bad
    $ unset IFS
    $ echo "$*"
    foo bar bad
    $ IFS=' '
    $ echo "$*"
    foo bar bad
    $ set zxc vbn mjg
    $ echo "$*"
    zxc vbn mjg
    

    try_var.sh

    #!/bin/sh
    arg="Hello"
    echo $arg
    echo "The program $0 is now running"
    echo "The seconed parameter was $2"
    echo "The first parameter was $1"
    echo "The parameter list was $*"
    echo "The parameter list was $@"
    echo "The user's home directory is $HOME"
    echo "Please input a new greeting"
    read arg
    echo "$arg" now equals $arg
    echo "The script is now complete"
    exit 0
    

    执行如下

    $ chomd +x try_var.sh
    $ ./try_var.sh 111 ok hbk hhh
    Hello
    The program ./try_var.sh is now running
    The seconed parameter was ok
    The first parameter was 111
    The parameter list was 111 ok hbk hhh
    The parameter list was 111 ok hbk hhh
    The user's home directory is /home/hyper
    Please input a new greeting
    AI
    AI now equals AI
    The script is now complete
    
条件
  • test 或 [ 命令
    test -参数 <文件名> == [ -参数 <文件名> ] == [ -参数 <文件名>
    conditions.sh
    #!/bin/sh
    if [ -f /bin/bash ]
    then
        echo "file /bin/bash exists."
    fi
    if test -d /bin/bash
    then
        echo "/bin/bash is a directory."
    else
        echo "/bin/bash is NOT a directory."
    fi
    
    执行如下
    $ vim conditions.sh
    $ chmod +x conditions.sh
    $ ./conditions.sh
    file /bin/bash exists.
    /bin/bash is NOT a directory.
    
控制结构
  1. if 语句
    #!/bin/sh
    echo "Is it morning? Please answer yes or no"
    read timeofday
    if [ $timeofday = "yes" ]; then
        echo "Good morning."
    else
        echo "Good afternoon."
    fi
    exit 0
    
  2. elif 语句
    #!/bin/sh
    echo "Is it morning? Please answer yes or no"
    read timeofday
    if [ $timeofday = "yes" ]
    then
        echo "Good morning."
    elif [ $timeofday = "no" ]
    then
        echo "Good afternoon."
    else
        echo "Sorry, $timeofday not recognized. Enter yes or no."
        exit 1
    fi
    exit 0
    
  3. 潜藏的bug
    如果不回答问题,直接按下回车键,将看到以下信息:
    $ ./elif.sh
    Is it morning? Please answer yes or no
    
    ./elif.sh: line 4: [: =: unary operator expected
    ./elif.sh: line 7: [: =: unary operator expected
    Sorry,  not recognized. Enter yes or no.
    
    [Bug]输入回车,将导致if [ = "yes" ],而这不是一个合法的条件。应修改为if [ "$timeofday" = "yes" ]
  4. for 语句
    for1.sh
    #!/bin/sh
    for foo in bar fub 43
    do
        echo $foo
    done
    exit 0
    
    执行如下
    $ ./for1 
    bar
    fub
    43
    
    for2.sh
    #!/bin/sh
    for foo in "bar fub 43"
    do
        echo $foo
    done
    exit 0
    
    执行如下
    $ ./for2
    bar fub 43
    
    for3.sh 打印当前目录中所有以字母 f 开头,以 .sh 结尾的脚本文件
    #!/bin/sh
    for file in $(ls f*.sh)
    do
        lpr $file
    done
    exit 0
    
    执行如下
    $ ./for3.sh 
    lpr: Error - No default destination.
    lpr: Error - No default destination.
    lpr: Error - No default destination.
    lpr: Error - No default destination.
    
    lpr (line printer,按行打印)实用程序用来将一个或多个文件放入打印队列等待打印。未连接打印机,所以出错,将 lpc 改为 echo 得到以下结果
    $ ./for3.sh 
    first.sh
    for1.sh
    for2.sh
    for3.sh
    
  5. while 语句
    while.sh
    #!/bin/sh
    echo "Enter password"
    read trythis
    while [ "$trythis" != "secret" ];do
        echo "Sorry,try again"
        read trythis
    done
    exit 0
    
    $ ./while.sh 
    Enter password
    qwert
    Sorry,try again
    secret
    
  6. until 语句
    循环将反复执行直到条件为真
    until.sh
    #!/bin/bash
    until who | grep "$1" > /dev/null
    do
        sleep 60
    done
    # now ring the bell and announce the expected user.
    echo -e '\a'
    echo "**** $1 has just logged in ****"
    exit 0
    
    $ ./until.sh 
    
    ****  has just logged in ****
    
  7. case 语句
    将最精确的匹配放在最开始,最一般化的匹配放在最后。
    case1.sh
    #!/bin/sh
    echo "Is it morning? Please answer yes or no "
    read timeofday
    case "$timeofday" in
        yes) echo "Good Morning";;
        no ) echo "Good Afternoon";;
        y  ) echo "Good Morning";;
        n  ) echo "Good Afternoon";;
        *  ) echo "Sorry,answer not recongized";;
    esac
    exit 0  
    
    case2.sh
    #!/bin/sh
    echo "Is it morning? Please answer yes or no "
    read timeofday
    case "$timeofday" in
        yes | y | Yes | YES) echo "Good Morning";;
        n* | N* )            echo "Good Afternoon";;
        *  )                 echo "Sorry,answer not recongized";;
    esac
    exit 0  
    
    case3.sh
    #!/bin/sh
    echo "Is it morning? Please answer yes or no "
    read timeofday
    case "$timeofday" in
        yes | y | Yes | YES ) echo "Good Morning"
                              echo "Up bright and early this morning"
                              ;;
        [nN]* )               echo "Good Afternoon";;
        *  )                  echo "Sorry,answer not recongized"
                              echo "Please answer yes or no"
                              exit 1
                              ;;
    esac
    exit 0  
    
    case3.sh 执行如下
    $ ./case3.sh 
    Is it morning? Please answer yes or no 
    y
    Good Morning
    Up bright and early this morning
    $ ./case3.sh 
    Is it morning? Please answer yes or no 
    Y
    Sorry,answer not recongized
    Please answer yes or no
    $ ./case3.sh 
    Is it morning? Please answer yes or no 
    n
    Good Afternoon
    $ ./case3.sh 
    Is it morning? Please answer yes or no 
    N
    Good Afternoon
    $ ./case3.sh 
    Is it morning? Please answer yes or no 
    nNNNNN
    Good Afternoon
    $ ./case3.sh 
    Is it morning? Please answer yes or no 
    NNNNNNNNNNNNNNN
    Good Afternoon
    
    可以看出 [] 中的字母任意匹配,可将 Morning 的匹配项改为如下 [yY] | [Yy][Ee][Ss] )
  8. 命令列表
  • AND 列表
    state1 && state2 && state3 && ...
    state1 则继续向右执行,否则有一 则停止执行。
    and.sh
    #!/bin/sh
    touch file_one
    rm -f file_two
    if [ -f file_one ] && echo "hello" && [ -f file_two ] && echo " there"
    then echo "in if"
    else 
        echo "in else"
    fi
    exit 0
    
    执行如下
    $ ./and.sh 
    hello
    in else
    
  • OR 列表
    state1 || state2 || state3 || ...
    state1 则继续向右执行,否则有一 则停止执行。
    or.sh
    #!/bin/sh
    rm -f file_one
    if [ -f file_one ] || echo "hello" || echo " there"
    then echo "in if"
    else 
        echo "in else"
    fi
    exit 0
    
    执行如下
    $ ./or.sh 
    hello
    in if
    
  • AND 结合 OR 使用
    [ -f file_one ] && command for true || command for false 相当于 C 语言 ? : 表达式
  1. 语句块
    get_confirm && {
        grep -v "$cdcatnum" $tracks_file > $temp_file
        cat $temp_file > $tracks_file
        echo
        add_record_tracks
    }
    
函数
  • foo.sh
    #!/bin/sh
    foo()
    {
        echo "Function foo is executing"
    }
    echo "script starting"
    foo
    echo "script ended"
    exit 0
    
    执行如下
    $ ./foo.sh 
    script starting
    Function foo is executing
    script ended
    
  • foo2.sh
    #!/bin/sh
    sample_text="global variable"
    foo()
    {
        local sample_text="local variable"
        echo "Function foo is executing"
        echo $sample_text
    }
    echo "script starting"
    echo $sample_text
    foo
    echo "script ended"
    echo $sample_text
    exit 0
    
    执行如下
    $ ./foo2.sh 
    script starting
    global variable
    Function foo is executing
    local variable
    script ended
    global variable
    
  • return.sh
    #!/bin/sh
    yes_or_no()
    {
        echo "Is your name $* ?"
        while true
        do
            echo -n "Enter yes or no: "
            read x
            case "$x" in
                y | yes ) return 0;;
                n | no  ) return 1;;
                *       ) echo "Answer yes or no"
            esac
        done
    }
    echo "Original paramemters are $*"
    if yes_or_no "$1"
    then 
        echo "Hi $1, nice name"
    else
        echo "Never mind"
    fi
    exit 0
    
    执行如下
    $ ./return.sh Rick Neil
    Original paramemters are Rick Neil
    Is your name Rick ?
    Enter yes or no: y 
    Hi Rick, nice name
    $ ./return.sh Rick Neil
    Original paramemters are Rick Neil
    Is your name Rick ?
    Enter yes or no: n
    Never mind
    
    • 输入 y 返回 0 为什么会进入 if 分支?
    • 输入 n 返回 1 为什么会进入 else 分支?

每一条 Shell 命令,不管是 Bash 内置命令(例如 cdecho),还是外部的 Linux 命令(例如 lsawk),还是自定义的 Shell 函数,当它退出(运行结束)时,都会返回一个比较小的整数值给调用(使用)它的程序,这就是命令的退出状态(exit statu)。

很多 Linux 命令其实就是一个C语言程序,熟悉C语言的读者都知道,main() 函数的最后都有一个return 0,如果程序想在中间退出,还可以使用exit 0,这其实就是C语言程序的退出状态。当有其它程序调用这个程序时,就可以捕获这个退出状态。

if 语句的判断条件,从本质上讲,判断的就是命令的退出状态。

按照惯例来说,退出状态为 0 表示“成功”;也就是说,程序执行完成并且没有遇到任何问题。除 0 以外的其它任何退出状态都为“失败”。

之所以说这是“惯例”而非“规定”,是因为也会有例外,比如 diff 命令用来比较两个文件的不同,对于“没有差别”的文件返回 0,对于“找到差别”的文件返回 1,对无效文件名返回 2。

有编程经验的读者请注意,Shell 的这个部分与你所熟悉的其它编程语言正好相反:在C语言、C++、Java、Python 中,0 表示“假”,其它值表示“真”。

在 Shell 中,有多种方式取得命令的退出状态,其中 $? 是最常见的一种。我们不妨来看一下它的退出状态。请看下面的代码:

#!/bin/bash
read a
read b
(( $a == $b ));
echo "退出状态:"$?
运行结果1:
26
26
退出状态:0
运行结果2:
17
39
退出状态:1
命令
  1. break 命令
    用于跳出 for, until, while,可接收数值参数表示跳出循环的层数
    break.sh

    #!/bin/sh
    rm -rf fred*
    echo > fred1
    echo > fred2
    mkdir  fred3
    echo > fred4
    for file in fred*
    do
        if [ -d "$file" ]; then
            break;
        fi
    done
    echo first directory starting fred was $file
    rm -rf fred*
    exit 0
    

    执行如下

    $ ./break.sh 
    first directory starting fred was fred3
    
  2. : 命令
    空命令,偶尔用在条件逻辑中表示 true

    #!/bin/sh
    rm -f fred
    if [ -f fred ]; then
        :
    else
        echo file fred did not exist
    fi 
    exit 0
    

    执行如下

    $ ./:.sh
    file fred did not exist
    
  3. continue 命令
    用于跳过本次 for, until, while,可接收数值参数表示跳出循环的层数
    break.sh

    #!/bin/sh
    rm -rf fred*
    echo > fred1
    echo > fred2
    mkdir  fred3
    echo > fred4
    for file in fred*
    do
        if [ -d "$file" ]; then
            break;
        fi
    done
    echo first directory starting fred was $file
    rm -rf fred*
    exit 0
    

    执行如下

    $ ./break.sh 
    first directory starting fred was fred3
    
  4. . 命令
    环境设置,类似于 C/C++ 中的 #include

  5. echo 命令
    终端输出

  6. eval 命令
    对参数求值

  7. exec 命令
    将当前 shell 替换为一个不同的程序

    exec wall "Thanks for all the fish"
    

    修改当前文件描述符

    exec 3< afile
    
  8. exit n 命令
    使脚本程序以退出码n结束

    退出码说明
    126文件不可执行
    127命令未找到
    128+出现一个信号
    0成功
  9. export 命令
    导出变量到子shell
    export2.sh

    #!/bin/sh
    echo "$foo"
    echo "$bar"
    

    export1.sh

    #!/bin/sh
    foo="The first meta-syntactic variable"
    export bar="the second meta-synatactic variable"
    export2
    

    执行如下

    $ ./export1 
    ./export1: line 4: export2: command not found
    
  10. expr 命令
    表达式求值

  11. printf 命令

    $ printf "%s\n" hello
    hello
    $ printf "%s %d\t%s" "Hi There" 15 people
    Hi There 15	people
    
  12. return 命令
    若不制定返回参数,则默认返回最后一条命令的退出码。

  13. set 命令
    设置shell参数变量

  14. shift 命令
    将所有参数变量左移一个位置

  15. trap 命令
    用于在接受到信号后将要采取的行动

  16. unset 命令
    从环境变量中删除变量或函数

  17. find grep 正则表达式

  • find
    find [path] [options] [tests] [actions]

    • 当前目录 下查找以字母 c 开始的 文件
      $ find . -name "c*" -type f
      ./conditions.sh
      ./case3.sh
      ./case2.sh
      ./case1.sh
      
    • 在当前目录下查找比文件 foo.sh 新的 文件
      $ find . -newer foo.sh -type f -ls
      21102687      4 -rwxr-xr-x   1 hyper    hyper         126 2月 12 20:35 ./export1.sh
      21102688      4 -rwxr-xr-x   1 hyper    hyper          46 2月 12 20:33 ./export2.sh
      21102684      4 -rwxr-xr-x   1 hyper    hyper         276 2月 12 15:31 ./break.sh
      24772694      4 -rwxr-xr-x   1 hyper    hyper         238 2月 12 14:19 ./foo2.sh
      24772695      4 -rwxr-xr-x   1 hyper    hyper         499 2月 12 14:29 ./return.sh
      21102685      4 -rwxr-xr-x   1 hyper    hyper         129 2月 12 15:38 ./:.sh
      
    • 当前目录 下查找以字母 c 开始的 或 比文件 foo.sh 新的 文件
      $ find . \( -newer foo.sh -or -name "c*" \) -type f -ls
      24772680      4 -rwxr-xr-x   1 hyper    hyper         184 2月 11 20:52 ./conditions.sh
      21102687      4 -rwxr-xr-x   1 hyper    hyper         126 2月 12 20:35 ./export1.sh
      21102688      4 -rwxr-xr-x   1 hyper    hyper          46 2月 12 20:33 ./export2.sh
      21102684      4 -rwxr-xr-x   1 hyper    hyper         276 2月 12 15:31 ./break.sh
      24772689      4 -rwxr-xr-x   1 hyper    hyper         534 2月 12 13:07 ./case3.sh
      24772688      4 -rwxr-xr-x   1 hyper    hyper         301 2月 12 13:06 ./case2.sh
      24772694      4 -rwxr-xr-x   1 hyper    hyper         238 2月 12 14:19 ./foo2.sh
      24772695      4 -rwxr-xr-x   1 hyper    hyper         499 2月 12 14:29 ./return.sh
      24772687      4 -rwxr-xr-x   1 hyper    hyper         324 2月 12 12:46 ./case1.sh
      21102685      4 -rwxr-xr-x   1 hyper    hyper         129 2月 12 15:38 ./:.sh
      
  • grep
    grep [options] PATTERN [FILES]

    optionsmeaning
    -c输出匹配行的数目
    -v匹配模式取反——搜索不匹配的行
    -i忽略大小写
    ......
    • foo.sh 文件中匹配 in 出现的行
      $ grep in ./foo.sh
      #!/bin/sh
          echo "Function foo is executing"
      echo "script starting"
      
    • foo.shfoo2.sh 文件中匹配 in 出现的总行数
      $ grep -c in ./foo.sh ./foo2.sh 
      ./foo.sh:3
      ./foo2.sh:3
      
    • foo.shfoo2.sh 文件中匹配 in 不出现的总行数
      $ grep -c -v in ./foo.sh ./foo2.sh 
      ./foo.sh:6
      ./foo2.sh:11
      
  • 正则表达式

    charmeaning
    ^指向一行的开头
    $指向一行的结尾
    .任意单个字符
    []括号内包含一个字符范围,其中任何一个字符都可被匹配

    若使用上述字符作普通字符,须在其前加 \

    匹配模式含义
    [:alnum:]字母与数字字符
    [:alpha:]字母
    [:ascii:]ASCII字符
    [:blank:]空格或制表符
    [:cntrl:]ASCII控制字符
    [:digit:]数字
    [:graph:]非控制、非空格字符
    [:lower:]小写字母
    [:print:]可打印字符
    [:punct:]标点符号
    [:space:]空白字符
    [:upper:]大写字母
    [:xdigit:]十六进制数字

    扩展匹配 -E 选项

    选项含义
    ?匹配是可选的,但最多匹配一次
    *必须匹配0此或多次
    +必须匹配1此或多次
    {n}必须匹配n次
    {n,}必须匹配n次或n+次
    {n,m}必须匹配n~m次
    $ cat foo2.sh 
    #!/bin/sh
    sample_text="global variable"
    foo()
    {
        local sample_text="local variable"
        echo "Function foo is executing"
        echo $sample_text
    }
    echo "script starting"
    echo $sample_text
    foo
    echo "script ended"
    echo $sample_text
    exit 0
    
  • 在上述文件 foo2.sh 中查找以字母 e 开始的行:

    $ grep ^e ./foo2.sh
    echo "script starting"
    echo $sample_text
    echo "script ended"
    echo $sample_text
    exit 0
    
  • 在上述文件 foo2.sh 中查找以字符 " 结尾的行:

    $ grep \"$ ./foo2.sh
    sample_text="global variable"
        local sample_text="local variable"
        echo "Function foo is executing"
    echo "script starting"
    echo "script ended"
    
  • 在上述文件 foo2.sh 中查找以字母 o 结尾的单词:

    $ grep o[[:blank:]] ./foo2.sh 
        echo "Function foo is executing"
        echo $sample_text
    echo "script starting"
    echo $sample_text
    echo "script ended"
    echo $sample_text
    
  • 在上述文件 foo2.sh 中查找以字母 fo 开始的由 3 个字母组成的单词:

    $ grep fo.[[:space:]] ./foo2.sh 
    echo "Function foo is executing"
    
  • 在上述文件 foo2.sh 中查找只由 6 个字符长的全部 小写字母 组成的单词:

    $ grep -E [a-z]\{6\} ./foo2.sh 
    sample_text="global variable"
        local sample_text="local variable"
        echo "Function foo is executing"
        echo $sample_text
    echo "script starting"
    echo $sample_text
    echo "script ended"
    echo $sample_text
    
命令的执行
  • 算术扩展
    #!/bin/sh
    x=0
    while [ "$x" -ne 10 ]
    do 
        echo $x
        x=$(($x+1))
    done
    exit 0
    
综合应用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值