博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
shell基础
阅读量:7121 次
发布时间:2019-06-28

本文共 14350 字,大约阅读时间需要 47 分钟。

hot3.png

数组

shell数组用括号表示,元素用空格符分隔。

获取数组元素: ${array[index]} 获取数组所有元素: ${array[]} 获取数组长度:${#array[]}

grep:查找文件中是否包含字符串

!取反

shell中取反操作使用 ! 号,!号前后要有空格

cat 命令

cat用来查看文件,当cat不跟参数时,cat从标准输入STDIN读取数据,即输入什么,显示什么。如果把标准输入重定向到文件,那cat输出的结果就是文件的每一行数据。

命令替换:将命令的输出赋值给变量

反引号括起来的是命令,命令的结果会传递给currentTime变量 currentTime= `date `

或者 currentTime = $(date)

重定向

  • 输出重定向 ls -l > 1.log #将ls -l的结果输出到1.log

  • 输入重定向:将文件内容作为指令的输入 wc < 1.log #将1.log作为wc指令的参数

  • 内联输入重定向:指定文本当做输入数据开始和结束标志,以获得更多输入,直到输入了结束标志

wc << EOF> 111> 222> 333> EOF3       3      13

管道:一个命令的输出当做另一个命令的输入

ls -l | sort > 1.log #将ls -l的结果排序,然后重定向到1.log中ls -l | more #将ls的结果分屏显示

数学运算:

将数学表达式放在$[]中,可执行数学表达式,但是缺点是不能进行浮点数运算.

$[数学表达式]

$[1+2]$[3*4]

脚本中使用bash 计算器,可以进行浮点运算

value=$(echo “options; expression” | bc)val=$(echo “scale=4; 4 / 5” | bc) #scale是设置bc的小数点位数,然后执行4/5

通过内联输入重定向

#!/bin/bashvar1=10.46var2=43.67var3=33.2var4=71var5=$(bc << EOFscale=4a1=$var1*$var2b1=$var3*$var4a1+b1EOF)echo value=$var5~

简易计算器

支持输入多个数字及运算符,调用方式 ./test1 1+2*3

#!/bin/bashvalue=$(echo "scale=4; $1" | bc)echo value=$value

$? 查看命令的退出状态码

126代表没有权限设置脚本的退出码  exit 5  #脚本执行完后,以退出码5返回,退出码范围0-255

if语句

if command1then 	command2else   	command3fi

如果command1指令返回的状态码为0,执行command2,否则执行command3.else语句可选.

if command1then	command2elif command3then	command4fi

if语句无法判断数值或字符串比较,需要借助test表达式

#!/bin/basha=10if test a > 5then    echo "a > 5"elif test a > 10then    echo "a > 10"fi

或使[]表达式,[]两边必须要有空格,test表达式无法比较浮点数

#数值比较

  • -eq :相等
  • -ge:大于等于
  • -gt:大于
  • -le:小于等于
  • -lt:小于
  • -ne:不等于
#!/bin/bashif [ $1 -gt $2 ]then    echo "$1 >= $2"elif [ $1 -lt $2 ]then    echo "$1 < $2"elif [ $1 -eq $2 ]then    echo "$1 = $2"fi

#字符串比较

  • str1 > str2 str1是否大于str2
  • str1 < str2 str1是否小于str2
  • str1 = str2 str1是否等于str2
  • str1 != str2 str1是否不等于str2
  • -n str1: str1长度是否非0
  • -z str1: str1长度是否为0

当比较大于和小于的时候,需要对运算符进行转义,否则会当做重定向处理

name1=jermyname2=xiaobaiif [ $name1 = $name2 ]then    echo "=="fiif [ $name1 != $name2 ]then    echo "!="fiif [ $name1 \> $name2 ]then    echo ">"fiif [ $name1 \< $name2 ]then    echo "<"fiif [ -n $name1 ]then    echo "not 0"fiif [ -z $name1 ]then    echo "=0"fi

#文件比较

  • -d file: 检查file是否存在,并且是目录
  • -e file: 检查file是否存在
  • -f file:检查文件是否存在且是文件
  • -r file: 检查file是否存在且可读
  • -s file:检查file是否存在且非空
  • -w file:检查file是否存在且可写
  • -x file:检查file是否存在且可执行
  • -O file:检查file是否存在且属于当前用户
  • -G file:检查file是否存在且默认组与当前用户相同
  • file1 -nt file2 :检查file1是否比file2新
  • file1 -ot file2 :检查file1是否比file2旧

组合运算符

if [ condition1 ] && [ condition2 ]then       echofiif [ condition1 ] || [ condition2 ]then       echofi

双括号表达式

test表达式只能使用简单的算术操作,双括号提供了更多的数学符号,和其他语言里面的if语句可使用的数学符号相同。也可以用来赋值

a=10b=20if (( $a > $b ))then	echo “”fic=(( $a++ ))

双方括号表达式:用于字符串的模式匹配。双括号前后必须有空格

#!/bin/bashif [[ $USER == j* ]]then    echo "$USER start with j"else    echo "not start with j"fi检查用户名是否j开头。== 将右边的字符串视为一个模式,并应用模式匹配规则

case

case语句会将制定变量与不同模式匹配,如果匹配,则只需该模式的命令。可以使用竖线在一行中分隔多个模式。

#!/bin/bashcase $USER inxiaobai | xiaohei)    echo "xiaobai";;xiaohong)    echo "xiaohong";;jermy)    echo "jermy";;esac

for循环

for var in listdo	commandsdone#读取列表的值for name in xiaobai xiaohei xiaohong jermydo	echo $namedone

更改字段分隔符

系统默认的字段分隔符是空格 制表符 换行符,存储在IFS(内部字段分隔符)中,在处理字段时,可能需要忽略某些分隔符,此时可以通过修改IFS来达到目的。

#!/bin/bashOLDIFS=$IFS	#保存IFSIFS=$'\n'  	#设置新的IFSfor item in $(ls -l)do    echo $itemdoneIFS=$OLDIFS    #还原IFS#!/bin/bashOLDIFS=$IFSIFS=:;	#修改IFS为冒号、分号for i in "this:is:test:message"do     echo $idoneIFS=$OLDIFS

使用通配符读取目录

#!/bin/bashfor file in ./*do    if [ -d $file ]    	then echo “$file is a directory”    elif [ -f $file ]	then echo “$file is a file”    fidone

C语言格式的for循环

使用C语言的for循环,需要使用双括号

#!/bin/bashfor (( i=0;i<10;i++ ))do	echo $idone

while命令

循环开始执行test command,如果test command返回状态码0,执行other command,继续while循环,否则退出循环

while test commanddo	other commanddone
#!/bin/basha=10while [ $a -gt 0 ]do    echo $a    a=$[ $a - 1 ]done

until命令

只有 test command不返回状态0时,才会执行other command,如果返回0,循环退出

until test commanddo	other commanddone
#!/bin/basha=10until [ $a -eq 0 ]do    echo $a    a=$[ $a - 1 ]done

循环处理文件数据

#!/bin/bashIFSOLD=$IFSIFS=$'\n'for line in $(cat 1.txt)	#以换行为分隔读取每一行数据do    IFS=:		#以冒号为分隔,分隔每行数据    for text in $line    do	echo $text    donedoneIFS=$IFSOLD

跳出循环

  • break:当有嵌套循环时,break只会跳出内部循环,外部循环并未停止。break后可以跟参数,break 2跳出第二层级循环。
  • continue:终止某次循环命令,但并不会完全终止整个循环。 continue也可以跟层级,continue 2 终止第二层级当前循环

处理循环的输出

循环执行后,通过管道命令,可以对循环结果进行重定向或其他处理

#!/bin/bashIFSOLD=$IFSIFS=$'\n'for line in $(cat 1.txt)	#以换行为分隔读取每一行数据do    IFS=:		#以冒号为分隔,分隔每行数据    for text in $line    do	echo $text    donedone > 1.txt	#对循环结果重定向,# done | sort   #对循环结果排序IFS=$IFSOLD

##处理用户输入

位置参数

  • $0 程序名,根据执行脚本命令的不同,输出不同。
  • $1 第一个参数
  • $2 第二个参数,直到$9
  • 参数多于9个,引用是需要通过 ${10}的方式引用

$0会根据执行脚本的命令不同,输出不同,可以使用basename获取脚本名称

JermydeMacBook-Pro:shell jermy$ test2./test2JermydeMacBook-Pro:shell jermy$ ./test2./test2JermydeMacBook-Pro:shell jermy$ /Users/jermy/Desktop/shell/test2/Users/jermy/Desktop/shell/test2
#!/bin/bashname=$(basename $0)echo $nameJermydeMacBook-Pro:shell jermy$ test2test2JermydeMacBook-Pro:shell jermy$ ./test2test2JermydeMacBook-Pro:shell jermy$ /Users/jermy/Desktop/shell/test2test2

检测命令行参数

如果命令需要用户输入参数,但实际调用时没有加参数,指令执行会报错,所有需要在脚本中添加检查参数的判断。

#!/bin/bashif [ -n "$1" ]then echo "hello $1"elseecho "invalid parameter"fi

参数统计

当命令需要的参数过多时,检查每个参数比较麻烦,$#可以统计脚本运行时携带的参数个数。

#!/bin/bashif [ $# -ne 2 ]then    echo    echo Usage: test2.sh a b    echoelse    total=$[ $1+$2 ]    echo $totalfi
JermydeMacBook-Pro:shell jermy$ test2Usage: test2.sh a bJermydeMacBook-Pro:shell jermy$ JermydeMacBook-Pro:shell jermy$ test2 1Usage: test2.sh a bJermydeMacBook-Pro:shell jermy$ test2 1 23

获取最后一个参数

echo $#     #显示参数个数echo ${!#}	#获取最后一个参数

获取所有数据

  • $* 将命令行的所有参数当做一个单词保存,变成一个整体
  • $@ 将命令行的所有参数当做一个字符串中多个独立的单词,可以通过for遍历。

在mac上测试。这两个指令没什么区别。都可以通过for遍历

echo $*for item in $*do    echo $itemdoneecho $@for item in $@do    echo $itemdone
test2 aaaa bbbbb ccccaaaa bbbbb ccccaaaabbbbbccccaaaa bbbbb ccccaaaabbbbbcccc

移动变量 shift

shift命令会将每个参数的位置左移一个位置,变量$2会一道$1中,$1的值会被删除。$0的值是脚本名称,不会变。

如果需要一次性移动多个位置,需要给shift命令提供一个参数。 shift 2:移动2个位置,跳过不需要的参数。

//在不知道参数个数的情况下,通过shift,输出所有参数n=1while [ -n "$1" ]do    echo "index $n, value $1"    n=$[ $n+1 ]    shiftdone

处理选项

命令行选项和参数一样,可以像处理命令行参数一样处理命令行选项。

#处理简单选项

使用case语句,匹配选项,单独处理

#!/bin/bashwhile [ -n "$1" ]do    case $1 in    -a)    echo "get -a";;    -b)    echo "get -b";;    -c)    echo "get -c";;    esac    shiftdone
test2 -c -b -aget -cget -bget -a

#分离选项和参数

shell会使用“--”来分隔选项和参数,“--”之前是选项,之后是参数.

#!/bin/bashwhile [ -n "$1" ]do    case $1 in	-a) echo "get -a";;	-b) echo "get -b";;	-c) echo "get -c";;	--) shift	    break;;	*) echo "not an option"    esac    shiftdonecount=1for parma in $@do    echo "parma$count: $parma"    count=$[ $count + 1 ]done
test2 -a -b -c -- aaa bbb cccget -aget -bget -cparma1: aaaparma2: bbbparma3: ccc

#带值的选项

while [ -n "$1" ]do    case $1 in	-a) echo "find option -a";;	-b) param=$2	    echo "find option -b, param=$param"	    shift;;        -c) param=$2            echo "find option -c, param=$param"            shift;;	*) echo "invalid input"    esac    shiftdone
test2 -a -b eeeee -c rrrrrfind option -afind option -b, param=eeeeefind option -c, param=rrrrr

使用getopt命令

如果使用组合选项,比如-ab,上面列出的三种方式无法处理,这时就需要使用getopt命令。

getopt命令可以接收一系列任意形式的命令行选项和参数,并自动将他们转换成适当的格式。

getopt optstring parameters 你需要在optstring中列出每个命令行选项字母,在需要选项的字母后加冒号。

当指定了一个不在optstring的选项时,getopt会产生一个错误,如果想忽略这个错误,可以在命令后加-q选项。(这个选项在MAC上无效,会导致设置getopt失败)

set -- $(getopt ab:cd "$@")	#设置选项abcd,选项b带参数while [ -n "$1" ]do    case "$1" in	-a) echo "find option -a";;	-b) param="$2"            echo "find option -b,param=$param"	    shift;;	-c) echo "find option -c";;	-d) echo "find option -d";;    esac    shiftdone

getopt的缺点是选项参数有空格的话,会识别失败。

getopts

getopts相比getopt,能识别带空格的参数。

getopts会用到两个环境变量,OPTARG会保存参数值。OPTIND保存了参数列表正在处理的参数位置。

while getopts :ab:c opt		//:ab:c 是命令行选项形式,第一个冒号表示忽略找不到选项的错误。b后面的冒号表示选项b带参数。 opt保存getopts定义的参数。相比getopt,case语句中不需要加"-"do    case "$opt" in	a) echo "find -a option";;	b) echo "find -b option ,with value $OPTARG";;	c) echo "find -c option";;	*) echo "unknown option $opt"    esacdone

optstring中未定义的选项字母会以问号形式发送给代码。

getopts命令知道何时停止处理选项,并将参数留给你处理。在getopts处理每个选项时,

它会将OPTIND环境变量值增一。在getopts完成处理时,你可以使用shift命令和OPTIND值来 移动参数。

while getopts :ab:c optdo    case "$opt" in	a) echo "find option -a";;	b) echo "find option -b, with parma $OPTARG";;	c) echo "find option -c";;	*) echo "uknow option" ;;    esacdone#OPTIND保存了当前处理的选项位置,要获得后面的参数,需要左移参数shift $[ $OPTIND -1 ]count=1for param in "$@"do    echo "param $count: $param"    count=$[ $count+1 ]done
test2 -a -b 111 -c ad sfwf wfn wfind option -afind option -b, with parma 111find option -cparam 1: adparam 2: sfwfparam 3: wfnparam 4: w

获取用户输入

#基本读取

获取用户输入使用read命令,read param ,将用户输入保存到param中

// echo -n :不会在字符串末尾输出换行符,让提示信息和用户输入在一行显示echo -n "please input your nane"read nameecho "your name is $name"

#使用read -p 读取输入

read -p选项允许在命令行中指定提示符

read -p "please input your name: " nameecho "your name is $name"

如果需要用户输入多个数据时,read命令需要指定多个变量,如果变量数据不够,剩余的数据会保存到最后一个变量中。

如果read命令不指定变量,read会将收到的数据都放在REPLY环境变量中。

read -p "please input data: "n=1for data in $REPLYdo    echo "index: $n, data:$data"    n=$[ $n+1 ]done test2please input data: ff sf wek wkfsdf index: 1, data:ffindex: 2, data:sfindex: 3, data:wekindex: 4, data:wkfsdf

#输入超时 -t

-t选项可以指定输入超时时间,当计时器过期后,read指令会返回非0退出状态码

if read -t 5 -p "please input: " datathen    echo "your input is: $data"else    echo "timeout"fi

#指定输入字符个数 -n

-n 选项可以指定read指令输入字符个数,当用户输入指定字符个数后,read自动退出,将数据传递给变量

//当输入1个字符后,read指令自动退出read -n1 -p "please input: "echoecho "your input is $REPLY"

#隐藏读取 -s

当用户输入密码时,不希望密码显示在屏幕上,可以使用-s选项,实际上数据会显示,只是文字颜色被设成跟背景色一致。

read -s -p "please input: "echo echo "data: $REPLY"

#读取文件

read可以读取文件数据,每次调用read命令,会从文件中读取一行文本,当读取到文件末尾时,read会退出病房非0退出状态码。

count=1cat 1.txt | while read linedo    echo "line $count: $line"    count=$[ $count+1 ]doneecho "finish read file"

##呈现数据

标准文件描述符

Linux系统对每个对象当做文件处理,使用文件描述符标识每个对象。

  • 0 :STDIN 标准输入,键盘输入或输入重定向
  • 1 :STDOUT 标准输出,终端显示器
  • 2 :STDERR 标准错误输出

默认情况下STDOUT和STDERR文件描述符会执行同一个位置,即终端显示器。当对STDOUT重定向后,STDERR不会发生改变,即STDERR的消息还是会显示在屏幕上。

重定向错误数据

#只重定向错误数据

//将错误数据重定向到1.log中ls -l 1.fff 2> 1.log

#重定向数据和错误

//将正确的数据重定向到1.log,错误的数据重定向到2.log ls -l 1.fff 1> 1.log 2> 2.log
//将数据和错误数据都重定向到1.logls -l 1.fff $> 1.log

脚本中重定向输出

#临时重定向

//这行会在脚本的STDERR文件描述符所指向的位置显示文本,而不是通常的STDOUTecho "this is an error" >$2//运行脚本时,如果重定向了STDERR,上面的错误信息会重定向到指定文本中test 2> 1.log

#永久重定向

使用exec命令,可以告诉shell在脚本执行期间重定向某个特定文件描述符.

exec 1>1.log	//将STDOUT重定向到1.logexec 2>2.log //将STDERR重定向到2.log

#重定向输入

exec命令允许将STDIN重定向到文件中

//设定1.txt为标准输入,从1.txt中读取数据exec 0< 1.txtwhile read linedo    echo "data is : $line"done

创建自己的重定向

#创建输出文件描述符

//将文件描述符3重定向到3.logexec 3> 3.logecho "this is test1"echo "this is test2"echo "this is test3" >&3 //这条语句输出在文件3中

#重定向文件描述符

exec 3>&1			//将文件描述符3重定向到1中,即STDOUTexec 1>1.log	    //将STDOUT重定向到1.logecho "this is test"  //标准输出,会输出到1.logecho "this is test" >&3 //因为文件描述符3现在定向在STDOUT,所以这个语句会显示在屏幕上exec 1>&3        //将文件描述符1重定向到STDOUT

#创建输入文件描述符

可以先将STDIN重定向到其他文件描述符,读取完文件后再将STDIN还原。

exec 6<&0  	//将STDIN重定向到文件描述符6exec 0<1.log //将文件描述符0重定向到1.log,即1.log是数据输入源n=1while read line	//通过read命令从输入源读数据do    echo "line$n: $line"    n=$[ $n+1 ]doneexec 0<&6	//还原文件描述符read -n1 -p "is done? Y|N :" flag //从标准输入源输入数据echocase $flag iny | Y)    echo "done!!!";;n | N)    echo "not done!!!"esac

#关闭文件描述符

exec 3>&-		//关闭文件描述符3

#列出打开的文件描述符

lsof 命令会列出整个Linux系统打开的所有文件描述符。

  • -p: 指定进程ID
  • -d: 指定文件描述符编号
// -a 表示逻辑与运算// $$ 获取当前的PID /usr/sbin/lsof -a -p $$ -d 0,1,2

#阻止命令输出

当脚本作为后台进程运行时,不需要显示脚本输出。可以将STDERR重定向到一个叫null文件的特殊文件。

路径:/dev/null

重定向到null文件的任何数据都会被丢掉,不会显示。

ls -al xxx 2> /dev/null 	//将STDERR重定向到null文件,会忽略所有错误输出

null文件另外一个功能是清空文件中的数据

cat /dev/null > test  //将null文件重定向到test中,清空test数据

临时文件

Linux系统下/tmp目录存放不需要永久保存的文件,mktemp命令可以在当前脚本目录下创建一个临时文件。

#创建本地临时文件

mktemp testing.XXXXXX   //参数格式:文件名.XXXXXX,系统会自动补全6个字符mktemp -d test.XXXX //创建临时文件夹
tempFile=$(mktemp test.XXXXXX)	//创建临时文件exec 3>$tempFile		//文件描述符3输出到临时文件echo "this is test1" >&3 echo "this is test2" >&3exec 3>&- //关闭文件描述符echo "content is :"cat $tempFilerm -f $tempFile >/dev/null //删除临时文件

#在系统临时目录下创建临时文件

mktemp是在脚本所在的目录创建临时文件,使用-t选项,可以在系统的临时目录创建文件

mktemp -t test.XXXX

记录消息

将输出同时发送给显示器和日志文件,需要使用tee命令。tee命令将从STDIN过来的数据同时发给STDOUT和tee指定的文件名。由于tee会重定向来自STDIN的视乎,可以配合管道命令重定向输出。

date | tee 1.log  //在显示器和文件同时显示date命令的结果,默认会覆盖输出文件的内容date | tee -a 1.log //以追加的方式输出,不覆盖输出文件的内容

##控制脚本

处理信号

Linux通过信号和系统中的进程进行通信。

  • Ctrl+C 中断进程,发送SIGINT信号
  • Ctrl+Z 暂停进程,发送SIGTSTP信号

捕获信号

trap commands signals

//捕获Ctrl+C中断退出信号trap "echo i got signal Ctrl+C" SIGINTecho startn=1while [ $n -lt 10 ]do    echo $n    sleep 1    n=$[ $n+1 ]done

捕获脚本退出的信号

//脚本退出的信号是EXIT,脚本执行完就会发出EXIT信号。trap "echo exit signal" EXITecho startn=1while [ $n -lt 5 ]do    echo $n    sleep 1    n=$[ $n+1 ]done

移除捕获

trap -- SIGINT //移除捕获SIGINT信号

后台模式运行脚本

后台模式运行脚本,只需要在命令后加个&就可以了.脚本会在后台运行,并显示作业号和PID。但后台进程仍然会共享STDIN和STDOUT,所有会在屏幕输出数据。当终端被关闭时,后台脚本也会停止。

test2 &	//后台模式运行test2

非控制台下运行脚本

让脚本一直在后台执行,直到结束。即使退出终端,脚本也不会停止。需要使用nohup命令。

nohup test2 &

nohup命令会解除终端与进程的关联,进程也就不再与STDOUT和STDERR联系在一起。nohup命令会自动将STDOUT和STDERR消息重定向到名为nohup.out文件中。

作业控制

jobs命令 查看当前进程的所有作业,作业前面带加号的代表当前默认作业,带减号的作业将成为下一个默认作业。

  • bg:以后台模式重启暂停的作业。 作业通过Ctrl+Z暂停后,通过jobs能获取暂停的作业号,通过bg 作业号,将对应的作业在后台继续运行。
  • fg:以前台模式重启暂停的作业。

调度谦让度

Linux系统进程优先级由高到第为 -20~19.数值越大,优先级越低。

nice指令设置优先级: nice -n 10 test2 > 1.log & 设置test2优先级为10,输出重定向到1.log ,并且在后台运行。

renice:调整优先级: renice -p 5055 -n 0 调整PID为5055的作业的优先级为0

定时运行作业

#at命令执行作业

at -f filename time

##函数

创建函数

函数定义必须放在函数调用之前,否则会找不到方法。

//方式一function name {}    //定义函数//方式二test2() {}name  //调用函数test2

函数返回值

#使用return命令

return命令允许指定一个整数值来定义函数的退出状态码。执行完函数后需要使用$?指令获取返回码,返回码必须是0~255.

#使用函数输出

function test {    read -p "input a number :" num    echo $[ $num*2 ]	//这里不是通过return返回,而是通过echo输出}n=$(test) //获取test的输出echo "double value: $n"

函数中使用变量

#向函数传递参数

函数内部也可以使用$0 $1等环境变量,但是函数内部的环境变量和脚本的环境变量是不同的环境。在函数内部获得的环境变量是传递给函数的参数。

function test {    echo $[ $1+$2 ]}ret=$(test $1 $2)echo "res=$ret"

local:函数的内部变量如果和全局变量同名,会使用全局变量。如果需要使用局部变量,使用local指令。

#函数传递数组

function testit {    local newarray    newarray=$(echo $@)	//需要把数组元素分解成单个值,然后重新组合成新对象    echo "the new array is: ${newarray[*]}"}myarray=(1 2 3 4 5)echo "the original array is ${myarray[*]}"testit ${myarray[*]}

#从函数返回数组

function arraydblr {    local originarray    local newarray    local elements    local i    originarray=($(echo $@))    newarray=($(echo $@))    elements=$#    for(( i=0;i

函数递归

function factorial {    if [ $1 -eq 1 ]    then	echo 1    else	value=$(factorial $[ $1-1 ])	echo $[ $value * $1 ]    fi	}read -p "please input a number: " numres=$(factorial $num)echo "res is: $res"

转载于:https://my.oschina.net/mexiaobai1315/blog/3013698

你可能感兴趣的文章
拷贝继承
查看>>
[解题报告]Codeforces 105D Entertaining Geodetics
查看>>
Mongo之架构部署(Replica Sets+Sharding)
查看>>
小程序(一)
查看>>
POJ 2689
查看>>
java 继承 String类
查看>>
开始gentoo之旅
查看>>
自动化测试(三)
查看>>
PHP获取访客ip、系统、浏览器等信息[转]
查看>>
的记录
查看>>
CSS之设置p段落中的文字与页面左侧缩进两个字符!...
查看>>
给Android SDK设置环境变量
查看>>
迷茫的世界
查看>>
返回固定数据的web服务器
查看>>
视频信息查看,帧信息查看
查看>>
【python+flume+kafka+spark streaming】编写word_count入门示例
查看>>
PLSQL Developer简单使用教程
查看>>
浅谈分布式计算的开发与实现(二)
查看>>
linux下的chromedriver驱动器配置实例(含代码)
查看>>
spring2.5.6不兼容jdk8
查看>>