• 随堂练习 shell脚本(二)


    算术运算

    Shell允许在某些情况下对算术表达式进行求值,比如:let和declare 内置命令,(( ))复合命令和算术扩展。求值以固定宽度的整数进行,不检查溢出,尽管除以0 被困并标记为错误。运算符及其优先级,关联性和值与C语言相同。以下运算符列表分组为等优先级运算符级别。级别按降序排列优先。

    注意:bash 只支持整数,不支持小数

    id++ id--   variable post-increment and post-decrement
    ++id --id   variable pre-increment and pre-decrement
    - +   unary minus and plus
    ! ~   logical and bitwise negation
    **   exponentiation 乘方
    * / %   multiplication, division, remainder, %表示取模,即取余数,示例:9%4=1,5%3=2
    + -   addition, subtraction
    << >> l  eft and right bitwise shifts
    <= >= < >   comparison
    == !=   equality and inequality
    &   bitwise AND
    ^   bitwise exclusive OR
    |   bitwise OR
    && l  ogical AND
    ||   logical OR
    expr?expr:expr   conditional operator
    = *= /= %= += -= <<= >>= &= ^= |=   assignment
    expr1 , expr2   comma

    乘法符号有些场景中需要转义
    实现算术运算:

    1)let var =算术表达式

    2)((var=算术表达式))  和上面等价

    3)var=$[算术表达式]

    4)var=$((算术表达式))

    5)var=$(expr arg1 arg2  ... )

    6)declare -i var = 数值

    7)echo '算术表达式' | bc

    内建的随机数生成器变量:

    $RANDOM   取值范围:0 - 32767

    范例

    #生成 0 - 49 之间随机数
    echo $[$RANDOM%50]
    # 随机字体颜色
    [root@centos8 ~]# echo -e "33[1;$[RANDOM%7+31]hello33[0m"
    hello

    增强型赋值

    +=  i+=10 相当于 i=i+10

    -=  i-=j  相当于 i=i-j

    *=

    /=

    %=

    ++ i++,++i   相当于  i=i+1

    --  i--,--i    相当于 i=i-1

    格式

    let varOPERvalue

    [root@centos8 ~]# let i=10*2
    [root@centos8 ~]# echo $i
    20
    [root@centos8 ~]# ((j=i+10))
    [root@centos8 ~]# echo $j
    30

    范例

    #自加3后自赋值
    let count+=3
    [root@centos8 ~]# i=10
    [root@centos8 ~]# let i+=20   #相当于let i=i+20
    [root@centos8 ~]# echo $i
    30
    [root@centos8 ~]# j=20
    [root@centos8 ~]# let i*=j
    [root@centos8 ~]# echo $i

    600

    范例

    #自增,自减
    let var+=1
    let var++
    let var-=1
    let var--
    [root@centos8 ~]# unset i j ; i=1; let j=i++; echo "i=$i,j=$j"
    i=2,j=1
    [root@centos8 ~]# unset i j ; i=1; let j=++i; echo "i=$i,j=$j"
    i=2,j=2

    范例

    [root@centos8 ~]# expr 2 * 3
    expr: syntax error: unexpected argument ‘anaconda-ks.cfg’
    [root@centos8 ~]# ls
    anaconda-ks.cfg
    [root@centos8 ~]# expr 2 * 3
    6

    范例

    [root@centos8 ~]# echo "scale=3;20/3"|bc
    6.666

    范例

    [root@centos8 ~]# i=10
    [root@centos8 ~]# j=20
    [root@centos8 ~]# declare -i result=i*j
    [root@centos8 ~]# echo $result
    200

    范例:今有雉兔同笼,上有三十五头,下有九十四足,问雉兔各几何?

    #!/bin/bash

    HEAD=$1

    FOOT=$2

    ((RABBIT=(FOOT-HEAD-HEAD)/2))

    ((CHOOK=HEAD-RABBIT))

    echo RABBIT: $RABBIT

    echo CHOOK: $CHOOK

    逻辑运算

    1  true

    0  false

    与:&:和0相与,结果为0,和1相与,结果保留原值

    1 与 1 = 1

    1 与 0 = 0

    0 与 1 = 0

    0 与 0 = 0

    或:|:和1相或结果为1,和0相或,结果保留原值

    1 或 1 = 1

    1 或 0 = 1

    0 或 1 = 1

    0 或 0 = 0

    非:!

    !1 = 0   !  true

    ! 0 = 1  !  false

    异或:^
    异或的两个值,相同为假,不同为真。两个数字X,Y异或得到结果Z,Z再和任意两者之一X异或,将得出另一个值Y

    1 ^ 1 = 0
    0 ^ 0 = 0
    0 ^ 1 = 1
    1 ^ 0 = 1

    范例

    [root@centos8 ~]# true
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# false
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# ! true
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# ! false
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# x=10;y=20;temp=$x;x=$y;y=$temp;echo x=$x,y=$y
    x=20,y=10
    [root@centos8 ~]# x=10;y=20;x=$[x^y];y=$[x^y];x=$[x^y];echo x=$x,y=$y
    x=20,y=10

    短路运算

    短路与

    CMD1 短路与 CMD2
    第一个CMD1结果为真 (1),第二个CMD2必须要参与运算,才能得到最终的结果
    第一个CMD1结果为假 (0),总的结果必定为0,因此不需要执行CMD2

    短路或

    CMD1 短路或 CMD2
    第一个CMD1结果为真 (1),总的结果必定为1,因此不需要执行CMD2
    第一个CMD1结果为假 (0),第二个CMD2 必须要参与运算,才能得到最终的结果

    条件测试命令

    条件测试:判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成
    测试过程
    ,实现评估布尔声明,以便用在条件性环境下进行执行
    若真,则状态码变量 $? 返回0

    若假,则状态码变量 $? 返回1

    条件测试命令

      test EXPRESSION
      [ EXPRESSION ] #和test 等价,建议使用 [ ]
      [[ EXPRESSION ]]
    注意:EXPRESSION前后必须有空白字符

    变量测试

    # 判断 NAME 变量是否定义
    [ -v NAME ]
    # 判断 NAME 变量是否定义并且是名称引用,bash 4.4新特性
    [ -R NAME ]

    范例

    [root@centos8 ~]# unset x
    [root@centos8 ~]# test -v x
    [root@centos8 ~]# echo $?
    1

    [root@centos8 ~]# x=10
    [root@centos8 ~]# test -v x
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# y=
    [root@centos8 ~]# test -v y
    [root@centos8 ~]# echo $?
    0
    #注意 [ ] 需要空格,否则会报下面错误
    [root@centos8 ~]# [-v y]
    -bash: [-v: command not found
    [root@centos8 ~]# [ -v y ]
    [root@centos8 ~]# echo $?
    0

    数值测试

    -eq  是否等于

    -ne  是否不等于

    -gt  是否大于

    -ge  是否大于等于

    -lt   是否小于

    -le   是否小于等于

    范例

    [root@centos8 ~]# i=10
    [root@centos8 ~]# j=8
    [root@centos8 ~]# [ $i -lt $j ]
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# [ $i -gt $j ]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# [ i -gt j ]
    -bash: [: i: integer expression expected

    算术表达式比较

    <=
    >=
    <
    >

    范例

    [root@centos8 ~]# x=10;y=20;(( x > y )); echo $?
    1
    [root@centos8 ~]# x=10;y=20;(( x < y )); echo $?
    0

    字符串测试

    test 和 [ ] 用法

    -z STRING 字符串是否为空,没定义或空为真,不空为假,

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

    STRING1 = STRING2 是否等于,注意 = 前后有空格

    STRING1 != STRING2 是否不等于

    > ascii 码是否大于 ascii 码

    < 是否小于

    [[]] 用法

    [[ expression ]] 用法
    ==   左侧字符串是否和右侧的PATTERN相同
         注意:此表达式用于[[ ]]中,PATTERN为通配符
    =~   左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配
         注意: 此表达式用于[[ ]]中;扩展的正则表达式

    建议:当使用正则表达式或通配符使用[[ ]],其它情况一般使用 [ ]

    范例 :使用 [ ]

    [root@centos8 ~]# unset str
    [root@centos8 ~]# [ -z "$str" ]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# str=""
    [root@centos8 ~]# [ -z "$str" ]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# str=" "
    [root@centos8 ~]# [ -z "$str" ]
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# [ -n "$str" ]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# unset str
    [root@centos8 ~]# [ -n "$str" ]
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# [ "$str" ]
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# str=magedu
    [root@centos8 ~]# [ "$str" ]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# str=magedu
    [root@centos8 ~]# [ "$str" ]
    [root@centos8 ~]# echo $?

    0
    [root@centos8 ~]# str1=magedu
    [root@centos8 ~]# str2=mage
    [root@centos8 ~]# [ $str1 = $str2 ]
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# str2=magedu
    [root@centos8 ~]# [ $str1 = $str2 ]
    [root@centos8 ~]# echo $?
    0

    范例:在比较字符串时,建议变量放在“ ”中

    [root@centos8 ~]# [ "$NAME" ]
    [root@centos8 ~]# NAME="I love linux"
    [root@centos8 ~]# [ $NAME ]
    -bash: [: love: binary operator expected
    [root@centos8 ~]# [ "$NAME" ]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# [ I love linux ]
    -bash: [: love: binary operator expected

    范例:使用 [[ ]]

    #通配符
    [root@centos8 ~]# FILE=test.log
    [root@centos8 ~]# [[ "$FILE" == *.log ]]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# FILE=test.txt
    [root@centos8 ~]# [[ "$FILE" == *.log ]]
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# [[ "$FILE" != *.log ]]
    [root@centos8 ~]# echo $?
    0
    #正则表达式
    [root@centos8 ~]# [[ "$FILE" =~ .log$ ]]
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# FILE=test.log
    [root@centos8 ~]# [[ "$FILE" =~ .log$ ]]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# N=100
    [root@centos8 ~]# [[ "$N" =~ ^[0-9]+$ ]]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# N=Magedu10
    [root@centos8 ~]# [[ "$N" =~ ^[0-9]+$ ]]
    [root@centos8 ~]# echo $?
    1

    [root@centos8 ~]# IP=1.2.3.4
    [root@centos8 ~]# [[ "$IP" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$ ]]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# IP=1.2.3.4567
    [root@centos8 ~]# [[ "$IP" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$ ]]
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# [[ $IP =~ ^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3} ([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]
    [root@centos8 ~]# echo $?
    1
    #通配符
    [root@centos8 ~]# NAME="linux1"
    [root@centos8 ~]# [[ "$NAME" == linux* ]]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# [[ "$NAME" == "linux*" ]]
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# NAME="linux*"
    [root@centos8 ~]# [[ "$NAME" == "linux*" ]]
    [root@centos8 ~]# echo $?
    0
    # 结论:[[ == ]] == 右侧的 * 做为通配符,不要加“”,只想做为*, 需要加“” 或转义

    文件测试

    存在性测试

    -a FILE  同 -e

    -e FILE  文件存在性测试,存在为真,否则为假

    -b FILE  是否存在且为块设备文件

    -c FILE  是否存在且为字符设备文件

    -d FILE  是否存在且为目录文件

    -f FILE  是否存在且为普通文件

    -h FILE 或 -L FILE  存在且为符号链接文件

    -p FILE  是否存在且为命名管道文件

    -s FILE  是否存在且为套接字文件

    范例

    [root@centos8 ~]# [ -a /etc/nologin ]
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# ! [ -a /etc/nologin ]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# [ -d /etc ]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# [ -d /etc/issue ]
    [root@centos8 ~]# echo $?

    1
    [root@centos8 ~]# [ -L /bin ]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# [ -L /bin/ ]
    [root@centos8 ~]# echo $?
    1

    文件权限测试

    -r FILE  是否存在且可读

    -w FILE  是否存在且可写

    -x FILE  是否存在且可执行

    -u FILE  是否存在且拥有 suid 权限

    -g FILE  是否存在且拥有 sgid 权限

    -k FILE  是否存在且拥有 Sticky 权限

    注意:最终结果由用户对文件的实际权限决定,而非文件属性决定

    范例

    [root@centos8 ~]# [ -w /etc/shadow ]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# [ -x /etc/shadow ]
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# [ -w test.txt ]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# chattr +i test.txt
    [root@centos8 ~]# lsattr test.txt
    ----i-------------- nianling.txt
    [root@centos8 ~]# [ -w test.txt ]
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# chattr -i test.txt
    [root@centos8 ~]# [ -w test.txt ]
    [root@centos8 ~]# echo $?
    0

    文件属性测试

    -s FILE   #是否存在且非空
    -t fd         #fd 文件描述符是否在某终端已经打开
    -N FILE   #文件自从上一次被读取之后是否被修改过
    -O FILE   #当前有效用户是否为文件属主
    -G FILE   #当前有效用户是否为文件属组
    FILE1 -ef FILE2   #FILE1是否是FILE2的硬链接
    FILE1 -nt FILE2   #FILE1是否新于FILE2(mtime)
    FILE1 -ot FILE2   #FILE1是否旧于FILE2

    关于 ()和 {}

    (CMD1;CMD2;...)和 { CMD1;CMD2;...; } 都可以将多个命令组合在一起,批量执行

    [root@centos8 ~]# man bash

    ( list ) 会开启子shell,并且list中变量赋值及内部命令执行后,将不再影响后续的环境,帮助参看:man bash 搜索(list)
    { list; } 不会启子shell, 在当前shell中运行,会影响当前shell环境帮助参看:man bash 搜索{ list; }

    范例: () 和 {}

    [root@centos8 ~]# name=mage;(echo $name;name=wang;echo $name );echo $name
    mage
    wang
    mage
    [root@centos8 ~]# name=mage;{ echo $name;name=wang;echo $name; } ;echo $name
    mage
    wang
    wang
    [root@centos8 ~]# umask
    0022
    [root@centos8 ~]# (umask 066;touch f1.txt)
    [root@centos8 ~]# ll f1.txt
    -rw------- 1 root root 0 Dec 23 16:58 f1.txt
    [root@centos8 ~]# umask
    0022
    [root@centos8 ~]# ( cd /data;ls )
    test.log
    [root@centos8 ~]# pwd
    /root
    [root@centos8 ~]# { cd /data;ls; }
    test.log
    [root@centos8 data]# pwd
    /data

    #()会开启子shell
    [root@centos8 ~]# echo $BASHPID
    1920
    [root@centos8 ~]# ( echo $BASHPID;sleep 100)
    1979
    [root@centos8 ~]# pstree -p
    ├─sshd(719)───sshd(1906)───sshd(1919)─┬─bash(1920)───bash(1979)───sleep(1980)

    #{ } 不会开启子shell
    [root@centos8 ~]# echo $BASHPID
    1920
    [root@centos8 ~]# { echo $BASHPID; }
    1920

    组合测试条件

    第一种方式 [ ]

    [ EXPRESSION1 -a EXPRESSION2 ] 并且,EXPRESSION1和EXPRESSION2都是真,结果才为真
    [ EXPRESSION1 -o EXPRESSION2 ] 或者,EXPRESSION1和EXPRESSION2只要有一个真,结果就为真
    [ ! EXPRESSION ]   取反

    说明: -a 和 -o 需要使用测试命令进行,[[ ]] 不支持

    范例

    [root@centos8 ~]# ll /data/scrips/test.sh
    -rw-r--r-- 1 root root 382 Dec 23 09:32 /data/scripts/test.sh
    [root@centos8 ~]# [ -f $FILE -a -x $FILE ]
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# chmod +x /data/scripts/test.sh
    [root@centos8 ~]# ll /data/scripts/test.sh
    -rwxr-xr-x 1 root root 382 Dec 23 09:32 /data/script40/test.sh
    [root@centos8 ~]# [ -f $FILE -a -x $FILE ]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# chmod -x /data/scripts/test.sh
    [root@centos8 ~]# ll /data/scripts/test.sh
    -rw-r--r-- 1 root root 382 Dec 23 09:32 /data/scripts/test.sh
    [root@centos8 ~]# [ -f $FILE -o -x $FILE ]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# [ -x $FILE ]
    [root@centos8 ~]# echo $?
    1
    [root@centos8 ~]# [ ! -x $FILE ]
    [root@centos8 ~]# echo $?
    0
    [root@centos8 ~]# ! [ -x $FILE ]
    0

    第二种方式

    COMMAND1 && COMMAND2 #并且,短路与,代表条件性的AND THEN如果COMMAND1 成功,将执行COMMAND2,否则,将不执行COMMAND2
    COMMAND1 || COMMAND2 #或者,短路或,代表条件性的OR ELSE如果COMMAND1 成功,将不执行COMMAND2,否则,将执行COMMAND2
    ! COMMAND   #非,取反

    [root@centos7 ~]# [ $[RANDOM%6] -eq 0 ] && rm -rf /* || echo "click"click

    范例

    [root@centos8 ~]# test "A" = "B" && echo "Strings are equal"
    [root@centos8 ~]# test "A"-eq "B" && echo "Integers are equal"
    [root@centos8 ~]# [ "A" = "B" ] && echo "Strings are equal"
    [root@centos8 ~]# [ "$A" -eq "$B" ] && echo "Integers are equal"
    [root@centos8 ~]# [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab
    [root@centos8 ~]# [ -z "$HOSTNAME" -o "$HOSTNAME" = "localhost.localdomain" ]&& hostname www.longwang.com
    [root@centos8 ~]# id wang &> /dev/null || useradd wang
    [root@centos8 ~]# id zhang &> /dev/null || useradd zhang
    [root@centos8 ~]# getent passwd zhang
    zhang:x:1002:1002::/home/zhang:/bin/bash
    [root@centos8 ~]# grep -q no_such_user /etc/passwd || echo 'No such user'
    No such user

    范例

    [root@centos8 ~]# [ -f “$FILE” ] && [[ “$FILE”=~ .*.sh$ ]] && chmod +x $FILE
    [root@centos8 ~]# ping -c1 -W1 172.16.0.1 &> /dev/null && echo '172.16.0.1 is up' || (echo '172.16.0.1 is unreachable'; exit 1)
    172.16.0.1 is up
    [root@centos8 ~]# IP=10.0.0.111;ping -c1 -W1 $IP &> /dev/null && echo $IP is up || echo $IP is down
    10.0.0.111 is down
    [root@centos8 ~]# IP=10.0.0.1;ping -c1 -W1 $IP &> /dev/null && echo $IP is up || echo $IP is down
    10.0.0.1 is up

    范例:&& 和 || 组合使用

    [root@centos8 ~]# NAME=wang; id $NAME &> /dev/null && echo "$NAME is exist"
    wang is exist
    [root@centos8 ~]# NAME=wange; id $NAME &> /dev/null || echo "$NAME is not exist"
    wange is not exist
    [root@centos8 ~]# NAME=wange; id $NAME &> /dev/null && echo "$NAME is exist" || echo "$NAME is not exist"
    wange is not exist
    [root@centos8 ~]# NAME=wang; id $NAME &> /dev/null && echo "$NAME is exist" || echo "$NAME is not exist"
    wang is exist
    [root@centos8 ~]# NAME=wang; id $NAME &> /dev/null && echo "$NAME is exist" || echo "$NAME is not exist"
    wang is exist
    [root@centos8 ~]# NAME=wang; id $NAME &> /dev/null || echo "$NAME is not exist" && echo "$NAME is exist"
    wang is exist

    [root@centos8 ~]# NAME=wange; id $NAME &> /dev/null || echo "$NAME is not exist" && echo "$NAME is exist"
    wange is not exist
    wange is exist

    # 结论:如果&& 和 || 混合使用,&& 要在前,|| 放在后

    [root@centos8 ~]# NAME=wange; id $NAME &> /dev/null && echo "$NAME is exist" || useradd $NAME
    [root@centos8 ~]# id wange
    uid=1002(wange) gid=1002(wange) groups=1002(wange)
    [root@centos8 ~]# NAME=wangge; id $NAME &> /dev/null && echo "$NAME is exist" || ( useradd $NAME; echo $NAME is created )
    wangge is created
    [root@centos8 ~]# id wangge
    uid=1003(wangge) gid=1003(wangge) groups=1003(wangge)
    [root@centos8 ~]# NAME=wanggege; id $NAME &> /dev/null && echo "$NAME is exist" || { useradd $NAME; echo $NAME is created; }
    wanggege is created

    范例:网络状态判断

    #!/bin/bash

    IP=10.0.0.100

    ping -c1 -W1 $IP &> /dev/null && echo "$IP is up" || { echo "$IP is unreachable"; exit; }

    echo "Script is finished"

    范例:磁盘空间的判断

    #!/bin/bash

    WARNING=80

    SPACE_USED=`df|grep '^/dev/sd'|tr -s ' ' % | cut -d% -f5 | sort -nr | head -n1`

    [ "$SPACE_USED" -ge $WARNING ] && echo "disk used is $SPACE_USED,will be full" | mail -s diskwaring root

    范例:磁盘空间和Inode号的检查脚本

    #!/bin/bash

    WARNING=80

    SPACE_USED=`df | grep '^/dev/sd' | grep -Eo '[0-9]+%' |tr -d % | sort -nr | head -n1`

    INODE_USED=`df -i |grep '^/dev/sd' |grep -Eo '[0-9]+%' | tr -d % | sort -nr | head -n1`

    [ "$SPACE_USED" -gt  $WARNING -o "$INODE_USED" -gt $WARNING ] && echo "DISK USED:$SPACE_USED%,INODE_USED:$INODE_USED,will be full" | mail -s "DISK Warning" root@llxuan0360@163.com

  • 相关阅读:
    Window7下安装openssl完整版(亲测实现)
    Android 使用OkHttp
    Android应用中使用AsyncHttpClient来异步网络数据
    Android开发okhttp,retrofit,android-async-http,volley?
    Android开源框架AsyncHttpClient (android-async-http)使用
    15 个最好的 Bootstrap 设计工具推荐
    Bootstrap+angularjs+MVC3+分页技术+角色权限验证系统
    PKU 1509 Glass Beads (最小表示法)
    SQL Server 数据库没有有效全部者的三种解决的方法
    javascript小白学习指南0---1
  • 原文地址:https://www.cnblogs.com/xuanlv-0413/p/13225172.html
Copyright © 2020-2023  润新知