diff --git a/command/accept.md b/command/accept.md new file mode 100644 index 0000000000..3edc635c3a --- /dev/null +++ b/command/accept.md @@ -0,0 +1,29 @@ +accept +=== + +指示打印系统接受发往指定目标打印机的打印任务 + +## 补充说明 + +**accept命令** 属于CUPS套件,用于指示打印系统接受发往指定目标打印机的打印任务。 + +### 语法 + +``` +accept(选项)(参数) +``` + +### 选项 + +``` +-E:当连接到服务器时强制加密; +-U:指定连接服务器时使用的用户名; +-h:指定连接服务器名和端口号。 +``` + +### 参数 + +目标:指定目标打印机。 + + + \ No newline at end of file diff --git a/command/apt-get.md b/command/apt-get.md new file mode 100644 index 0000000000..95a4e3a601 --- /dev/null +++ b/command/apt-get.md @@ -0,0 +1,92 @@ +apt-get +=== + +Debian Linux发行版中的APT软件包管理工具 + +## 补充说明 + +**apt-get命令** 是Debian Linux发行版中的APT软件包管理工具。所有基于Debian的发行都使用这个包管理系统。deb包可以把一个应用的文件包在一起,大体就如同Windows上的安装文件。 + +### 语法 + +``` +apt-get(选项)(参数) +``` + +### 选项 + +``` +-c:指定配置文件。 +``` + +### 参数 + +* 管理指令:对APT软件包的管理操作; +* 软件包:指定要操纵的软件包。 + +### 实例 + +使用apt-get命令的第一步就是引入必需的软件库,Debian的软件库也就是所有Debian软件包的集合,它们存在互联网上的一些公共站点上。把它们的地址加入,apt-get就能搜索到我们想要的软件。/etc/apt/sources.list是存放这些地址列表的配置文件,其格式如下: + +``` +deb web或[ftp地址] [发行版名字] main/contrib/non-[free] +``` + +我们常用的Ubuntu就是一个基于Debian的发行,我们使用apt-get命令获取这个列表,以下是我整理的常用命令: + +在修改`/etc/apt/sources.list`或者`/etc/apt/preferences`之后运行该命令。此外您需要定期运行这一命令以确保您的软件包列表是最新的: + +``` +apt-get update +``` + +安装一个新软件包: + +``` +apt-get install packagename +``` + +卸载一个已安装的软件包(保留配置文件): + +``` +apt-get remove packagename +``` + +卸载一个已安装的软件包(删除配置文件): + +``` +apt-get –purge remove packagename +``` + +会把已装或已卸的软件都备份在硬盘上,所以如果需要空间的话,可以让这个命令来删除你已经删掉的软件: + +``` +apt-get autoclean apt +``` + +这个命令会把安装的软件的备份也删除,不过这样不会影响软件的使用的: + +``` +apt-get clean +``` + +更新所有已安装的软件包: + +``` +apt-get upgrade +``` + +将系统升级到新版本: + +``` +apt-get dist-upgrade +``` + +定期运行这个命令来清除那些已经卸载的软件包的.deb文件。通过这种方式,您可以释放大量的磁盘空间。如果您的需求十分迫切,可以使用`apt-get clean`以释放更多空间。这个命令会将已安装软件包裹的.deb文件一并删除。大多数情况下您不会再用到这些.debs文件,因此如果您为磁盘空间不足 而感到焦头烂额,这个办法也许值得一试: + +``` +apt-get autoclean +``` + + + \ No newline at end of file diff --git a/command/apt-key.md b/command/apt-key.md new file mode 100644 index 0000000000..64766cbe0f --- /dev/null +++ b/command/apt-key.md @@ -0,0 +1,30 @@ +apt-key +=== + +管理Debian Linux系统中的软件包密钥 + +## 补充说明 + +**apt-key命令** 用于管理Debian Linux系统中的软件包密钥。每个发布的deb包,都是通过密钥认证的,apt-key用来管理密钥。 + +### 语法 + +``` +apt-key(参数) +``` + +### 参数 + +操作指令:APT密钥操作指令。 + +### 实例 + +``` +apt-key list #列出已保存在系统中key。 +apt-key add keyname #把下载的key添加到本地trusted数据库中。 +apt-key del keyname #从本地trusted数据库删除key。 +apt-key update #更新本地trusted数据库,删除过期没用的key。 +``` + + + \ No newline at end of file diff --git a/command/apt-sortpkgs.md b/command/apt-sortpkgs.md new file mode 100644 index 0000000000..f9d2416b38 --- /dev/null +++ b/command/apt-sortpkgs.md @@ -0,0 +1,28 @@ +apt-sortpkgs +=== + +Debian Linux下对软件包索引文件进行排序的工具 + +## 补充说明 + +**apt-sortpkgs命令** 是Debian Linux下对软件包索引文件进行排序的简单工具。 + +### 语法 + +``` +apt-sortpkgs(选项)(参数) +``` + +### 选项 + +``` +-s:使用源索引字段排序; +-h:显示帮助信息。 +``` + +### 参数 + +文件:指定要排序的包含debian包信息的索引文件。 + + + \ No newline at end of file diff --git a/command/aptitude.md b/command/aptitude.md new file mode 100644 index 0000000000..378997d327 --- /dev/null +++ b/command/aptitude.md @@ -0,0 +1,51 @@ +aptitude +=== + +Debian Linux系统中软件包管理工具 + +## 补充说明 + +**aptitude命令** 与apt-get命令一样,都是Debian Linux及其衍生系统中功能极其强大的包管理工具。与apt-get不同的是,aptitude在处理依赖问题上更佳一些。举例来说,aptitude在删除一个包时,会同时删除本身所依赖的包。这样,系统中不会残留无用的包,整个系统更为干净。它通过文本操作菜单和命令两种方式管理软件包。 + +### 语法 + +``` +aptitude(选项)(参数) +``` + +### 选项 + +``` +-h:显示帮助信息; +-d:仅下载软件包,不执行安装操作; +-P:每一步操作都要求确认; +-y:所有问题都回答“yes”; +-v:显示附加信息; +-u:启动时下载新的软件包列表。 +``` + +### 参数 + +操作命令:用户管理软件包的操作命令。 + +### 实例 + +以下是我总结的一些常用aptitude命令,仅供参考: + +``` +aptitude update #更新可用的包列表 +aptitude upgrade #升级可用的包 +aptitude dist-upgrade #将系统升级到新的发行版 +aptitude install pkgname #安装包 +aptitude remove pkgname #删除包 +aptitude purge pkgname #删除包及其配置文件 +aptitude search string #搜索包 +aptitude show pkgname #显示包的详细信息 +aptitude clean #删除下载的包文件 +aptitude autoclean #仅删除过期的包文件 +``` + +当然,你也可以在文本界面模式中使用 aptitude。 + + + \ No newline at end of file diff --git a/command/arch.md b/command/arch.md index 5c813b0a5d..53e27266df 100644 --- a/command/arch.md +++ b/command/arch.md @@ -5,7 +5,7 @@ arch ## 补充说明 -**arch命** 用于显示当前主机的硬件架构类型。arch命令等同于`命令name -m`在当前的Linux系统下,arch命令输出结果有:i386、i486、i586、alpha、sparc、arm、m68k、mips、ppc、i686等 +**arch命令** 用于显示当前主机的硬件架构类型。arch命令等同于`命令name -m`在当前的Linux系统下,arch命令输出结果有:i386、i486、i586、alpha、sparc、arm、m68k、mips、ppc、i686等 ### 语法 @@ -18,4 +18,7 @@ arch ``` arch x86_64 -``` \ No newline at end of file +``` + + + \ No newline at end of file diff --git a/command/awk.md b/command/awk.md new file mode 100644 index 0000000000..af1d00281a --- /dev/null +++ b/command/awk.md @@ -0,0 +1,1693 @@ +awk +=== + +文本和数据进行处理的编程语言 + +## 补充说明 + +**awk** 是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。 + +## awk命令格式和选项 + + **语法形式** + +``` +awk [options] 'script' var=value file(s) +awk [options] -f scriptfile var=value file(s) +``` + + **常用命令选项** + +* **-F fs   ** fs指定输入分隔符,fs可以是字符串或正则表达式,如-F: +* **-v var=value   ** 赋值一个用户定义变量,将外部变量传递给awk +* **-f scripfile  ** 从脚本文件中读取awk命令 +* **-m[fr] val   ** 对val值设置内在限制,-mf选项限制分配给val的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。 + +## awk模式和操作 + +awk脚本是由模式和操作组成的。 + +### 模式 + +模式可以是以下任意一个: + +* /正则表达式/:使用通配符的扩展集。 +* 关系表达式:使用运算符进行操作,可以是字符串或数字的比较测试。 +* 模式匹配表达式:用运算符`~`(匹配)和`~!`(不匹配)。 +* BEGIN语句块、pattern语句块、END语句块:参见awk的工作原理 + +### 操作 + +操作由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内,主要部分是: + +* 变量或数组赋值 +* 输出命令 +* 内置函数 +* 控制流语句 + +## awk脚本基本结构 + +``` +awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' file +``` + +一个awk脚本通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块3部分组成,这三个部分是可选的。任意一个部分都可以不出现在脚本中,脚本通常是被 **单引号** 或 **双引号** 中,例如: + +``` +awk 'BEGIN{ i=0 } { i++ } END{ print i }' filename +awk "BEGIN{ i=0 } { i++ } END{ print i }" filename +``` + +### awk的工作原理 + +``` +awk 'BEGIN{ commands } pattern{ commands } END{ commands }' +``` + +* 第一步:执行`BEGIN{ commands }`语句块中的语句; +* 第二步:从文件或标准输入(stdin)读取一行,然后执行`pattern{ commands }`语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。 +* 第三步:当读至输入流末尾时,执行`END{ commands }`语句块。 + + **BEGIN语句块** 在awk开始从输入流中读取行 **之前** 被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中。 + + **END语句块** 在awk从输入流中读取完所有的行 **之后** 即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块。 + + **pattern语句块** 中的通用命令是最重要的部分,它也是可选的。如果没有提供pattern语句块,则默认执行`{ print }`,即打印每一个读取到的行,awk读取的每一行都会执行该语句块。 + + **示例** + +``` +echo -e "A line 1nA line 2" | awk 'BEGIN{ print "Start" } { print } END{ print "End" }' +Start +A line 1 +A line 2 +End +``` + +当使用不带参数的`print`时,它就打印当前行,当`print`的参数是以逗号进行分隔时,打印时则以空格作为定界符。在awk的print语句块中双引号是被当作拼接符使用,例如: + +``` +echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1,var2,var3; }' +v1 v2 v3 +``` + +双引号拼接使用: + +``` +echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1"="var2"="var3; }' +v1=v2=v3 +``` + +{ }类似一个循环体,会对文件中的每一行进行迭代,通常变量初始化语句(如:i=0)以及打印文件头部的语句放入BEGIN语句块中,将打印的结果等语句放在END语句块中。 + +## awk内置变量(预定义变量) + +说明:[A][N][P][G]表示第一个支持变量的工具,[A]=awk、[N]=nawk、[P]=POSIXawk、[G]=gawk + +``` + **$n** 当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段。 + **$0** 这个变量包含执行过程中当前行的文本内容。 +[N] **ARGC** 命令行参数的数目。 +[G] **ARGIND** 命令行中当前文件的位置(从0开始算)。 +[N] **ARGV** 包含命令行参数的数组。 +[G] **CONVFMT** 数字转换格式(默认值为%.6g)。 +[P] **ENVIRON** 环境变量关联数组。 +[N] **ERRNO** 最后一个系统错误的描述。 +[G] **FIELDWIDTHS** 字段宽度列表(用空格键分隔)。 +[A] **FILENAME** 当前输入文件的名。 +[P] **FNR** 同NR,但相对于当前文件。 +[A] **FS** 字段分隔符(默认是任何空格)。 +[G] **IGNORECASE** 如果为真,则进行忽略大小写的匹配。 +[A] **NF** 表示字段数,在执行过程中对应于当前的字段数。 +[A] **NR** 表示记录数,在执行过程中对应于当前的行号。 +[A] **OFMT** 数字的输出格式(默认值是%.6g)。 +[A] **OFS** 输出字段分隔符(默认值是一个空格)。 +[A] **ORS** 输出记录分隔符(默认值是一个换行符)。 +[A] **RS** 记录分隔符(默认是一个换行符)。 +[N] **RSTART** 由match函数所匹配的字符串的第一个位置。 +[N] **RLENGTH** 由match函数所匹配的字符串的长度。 +[N] **SUBSEP** 数组下标分隔符(默认值是34)。 +``` + + **示例** + +``` +echo -e "line1 f2 f3nline2 f4 f5nline3 f6 f7" | awk '{print "Line No:"NR", No of fields:"NF, "$0="$0, "$1="$1, "$2="$2, "$3="$3}' +Line No:1, No of fields:3 $0=line1 f2 f3 $1=line1 $2=f2 $3=f3 +Line No:2, No of fields:3 $0=line2 f4 f5 $1=line2 $2=f4 $3=f5 +Line No:3, No of fields:3 $0=line3 f6 f7 $1=line3 $2=f6 $3=f7 +``` + +使用`print $NF`可以打印出一行中的最后一个字段,使用`$(NF-1)`则是打印倒数第二个字段,其他以此类推: + +``` +echo -e "line1 f2 f3n line2 f4 f5" | awk '{print $NF}' +f3 +f5 +``` + +``` +echo -e "line1 f2 f3n line2 f4 f5" | awk '{print $(NF-1)}' +f2 +f4 + +``` + +打印每一行的第二和第三个字段: + +``` +awk '{ print $2,$3 }' filename +``` + +统计文件中的行数: + +``` +awk 'END{ print NR }' filename +``` + +以上命令只使用了END语句块,在读入每一行的时,awk会将NR更新为对应的行号,当到达最后一行NR的值就是最后一行的行号,所以END语句块中的NR就是文件的行数。 + +一个每一行中第一个字段值累加的例子: + +``` +seq 5 | awk 'BEGIN{ sum=0; print "总和:" } { print $1"+"; sum+=$1 } END{ print "等于"; print sum }' +总和: +1+ +2+ +3+ +4+ +5+ +等于 +15 +``` + +## 将外部变量值传递给awk + +借助 **`-v`选项** ,可以将外部值(并非来自stdin)传递给awk: + +``` +VAR=10000 +echo | awk -v VARIABLE=$VAR '{ print VARIABLE }' +``` + +另一种传递外部变量方法: + +``` +var1="aaa" +var2="bbb" +echo | awk '{ print v1,v2 }' v1=$var1 v2=$var2 +``` + +当输入来自于文件时使用: + +``` +awk '{ print v1,v2 }' v1=$var1 v2=$var2 filename +``` + +以上方法中,变量之间用空格分隔作为awk的命令行参数跟随在BEGIN、{}和END语句块之后。 + +## awk运算与判断 + +作为一种程序设计语言所应具有的特点之一,awk支持多种运算,这些运算与C语言提供的基本相同。awk还提供了一系列内置的运算函数(如log、sqr、cos、sin等)和一些用于对字符串进行操作(运算)的函数(如length、substr等等)。这些函数的引用大大的提高了awk的运算功能。作为对条件转移指令的一部分,关系判断是每种程序设计语言都具备的功能,awk也不例外,awk中允许进行多种测试,作为样式匹配,还提供了模式匹配表达式~(匹配)和~!(不匹配)。作为对测试的一种扩充,awk也支持用逻辑运算符。 + +### 算术运算符 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符描述
+ -加,减
* / &乘,除与求余
+ - !一元加,减和逻辑非
^ ***求幂
++ --增加或减少,作为前缀或后缀
+ +例: + +``` +awk 'BEGIN{a="b";print a++,++a;}' +0 2 +``` + +注意:所有用作算术运算符进行操作,操作数自动转为数值,所有非数值都变为0 + +### 赋值运算符 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符描述
= += -= *= /= %= ^= **=赋值语句
+ +例: + +``` +a+=5; 等价于:a=a+5; 其它同类 +``` + +### 逻辑运算符 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符描述
||逻辑或
&&逻辑与
+ +例: + +``` +awk 'BEGIN{a=1;b=2;print (a>5 && b<=2),(a>5 || b<=2);}' +0 1 +``` + +### 正则运算符 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符描述
~ ~!匹配正则表达式和不匹配正则表达式
+ +例: + +``` +awk 'BEGIN{a="100testa";if(a ~ /^100*/){print "ok";}}' +ok +``` + +### 关系运算符 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符描述
< <= > >= != ==关系运算符
+ +例: + +``` +awk 'BEGIN{a=11;if(a >= 9){print "ok";}}' +ok +``` + +注意:> < 可以作为字符串比较,也可以用作数值比较,关键看操作数如果是字符串就会转换为字符串比较。两个都为数字才转为数值比较。字符串比较:按照ASCII码顺序比较。 + +### 其它运算符 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符描述
$字段引用
空格字符串连接符
?:C条件表达式
in数组中是否存在某键值
+ +例: + +``` +awk 'BEGIN{a="b";print a=="b"?"ok":"err";}' +ok +``` + +``` +awk 'BEGIN{a="b";arr[0]="b";arr[1]="c";print (a in arr);}' +0 +``` + +``` +awk 'BEGIN{a="b";arr[0]="b";arr["b"]="c";print (a in arr);}' +1 +``` + +### 运算级优先级表 + +!级别越高越优先 +级别越高越优先 + +## awk高级输入输出 + +### 读取下一条记录 + +awk中`next`语句使用:在循环逐行匹配,如果遇到next,就会跳过当前行,直接忽略下面语句。而进行下一行匹配。net语句一般用于多行合并: + +``` +cat text.txt +a +b +c +d +e + +awk 'NR%2==1{next}{print NR,$0;}' text.txt +2 b +4 d +``` + +当记录行号除以2余1,就跳过当前行。下面的`print NR,$0`也不会执行。下一行开始,程序有开始判断`NR%2`值。这个时候记录行号是`:2` ,就会执行下面语句块:`'print NR,$0'` + +分析发现需要将包含有“web”行进行跳过,然后需要将内容与下面行合并为一行: + +``` +cat text.txt +web01[192.168.2.100] +httpd ok +tomcat ok +sendmail ok +web02[192.168.2.101] +httpd ok +postfix ok +web03[192.168.2.102] +mysqld ok +httpd ok +0 +awk '/^web/{T=$0;next;}{print T":t"$0;}' test.txt +web01[192.168.2.100]: httpd ok +web01[192.168.2.100]: tomcat ok +web01[192.168.2.100]: sendmail ok +web02[192.168.2.101]: httpd ok +web02[192.168.2.101]: postfix ok +web03[192.168.2.102]: mysqld ok +web03[192.168.2.102]: httpd ok +``` + +### 简单地读取一条记录 + +`awk getline`用法:输出重定向需用到`getline函数`。getline从标准输入、管道或者当前正在处理的文件之外的其他输入文件获得输入。它负责从输入获得下一行的内容,并给NF,NR和FNR等内建变量赋值。如果得到一条记录,getline函数返回1,如果到达文件的末尾就返回0,如果出现错误,例如打开文件失败,就返回-1。 + +getline语法:getline var,变量var包含了特定行的内容。 + +awk getline从整体上来说,用法说明: + +* **当其左右无重定向符`|`或`<`时:** getline作用于当前文件,读入当前文件的第一行给其后跟的变量`var`或`$0`(无变量),应该注意到,由于awk在处理getline之前已经读入了一行,所以getline得到的返回结果是隔行的。 +* **当其左右有重定向符`|`或`<`时:** getline则作用于定向输入文件,由于该文件是刚打开,并没有被awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行。 + + **示例:** + +执行linux的`date`命令,并通过管道输出给`getline`,然后再把输出赋值给自定义变量out,并打印它: + +``` +awk 'BEGIN{ "date" | getline out; print out }' test +``` + +执行shell的date命令,并通过管道输出给getline,然后getline从管道中读取并将输入赋值给out,split函数把变量out转化成数组mon,然后打印数组mon的第二个元素: + +``` +awk 'BEGIN{ "date" | getline out; split(out,mon); print mon[2] }' test +``` + +命令ls的输出传递给geline作为输入,循环使getline从ls的输出中读取一行,并把它打印到屏幕。这里没有输入文件,因为BEGIN块在打开输入文件前执行,所以可以忽略输入文件。 + +``` +awk 'BEGIN{ while( "ls" | getline) print }' +``` + +### 关闭文件 + +awk中允许在程序中关闭一个输入或输出文件,方法是使用awk的close语句。 + +``` +close("filename") +``` + +filename可以是getline打开的文件,也可以是stdin,包含文件名的变量或者getline使用的确切命令。或一个输出文件,可以是stdout,包含文件名的变量或使用管道的确切命令。 + +### 输出到一个文件 + +awk中允许用如下方式将结果输出到一个文件: + +``` +echo | awk '{printf("hello word!n") > "datafile"}' +或 +echo | awk '{printf("hello word!n") >> "datafile"}' +``` + +## 设置字段定界符 + +默认的字段定界符是空格,可以使用`-F "定界符"` 明确指定一个定界符: + +``` +awk -F: '{ print $NF }' /etc/passwd +或 +awk 'BEGIN{ FS=":" } { print $NF }' /etc/passwd +``` + +在`BEGIN语句块`中则可以用`OFS=“定界符”`设置输出字段的定界符。 + +## 流程控制语句 + +在linux awk的while、do-while和for语句中允许使用break,continue语句来控制流程走向,也允许使用exit这样的语句来退出。break中断当前正在执行的循环并跳到循环外执行下一条语句。if 是流程选择用法。awk中,流程控制语句,语法结构,与c语言类型。有了这些语句,其实很多shell程序都可以交给awk,而且性能是非常快的。下面是各个语句用法。 + +### 条件判断语句 + +``` +if(表达式) + 语句1 +else + 语句2 +``` + +格式中语句1可以是多个语句,为了方便判断和阅读,最好将多个语句用{}括起来。awk分枝结构允许嵌套,其格式为: + +``` +if(表达式) + {语句1} +else if(表达式) + {语句2} +else + {语句3} +``` + +示例: + +``` +awk 'BEGIN{ +test=100; +if(test>90){ + print "very good"; + } + else if(test>60){ + print "good"; + } + else{ + print "no pass"; + } +}' + +very good +``` + +每条命令语句后面可以用`;` **分号** 结尾。 + +### 循环语句 + +#### while语句 + +``` +while(表达式) + {语句} +``` + +示例: + +``` +awk 'BEGIN{ +test=100; +total=0; +while(i<=test){ + total+=i; + i++; +} +print total; +}' +5050 +``` + +#### for循环 + +for循环有两种格式: + +格式1: + +``` +for(变量 in 数组) + {语句} +``` + +示例: + +``` +awk 'BEGIN{ +for(k in ENVIRON){ + print k"="ENVIRON[k]; +} + +}' +TERM=linux +G_BROKEN_FILENAMES=1 +SHLVL=1 +pwd=/root/text +... +logname=root +HOME=/root +SSH_CLIENT=192.168.1.21 53087 22 +``` + +注:ENVIRON是awk常量,是子典型数组。 + +格式2: + +``` +for(变量;条件;表达式) + {语句} +``` + +示例: + +``` +awk 'BEGIN{ +total=0; +for(i=0;i<=100;i++){ + total+=i; +} +print total; +}' +5050 +``` + +#### do循环 + +``` +do +{语句} while(条件) +``` + +例子: + +``` +awk 'BEGIN{ +total=0; +i=0; +do {total+=i;i++;} while(i<=100) + print total; +}' +5050 +``` + +### 其他语句 + +* **break** 当 break 语句用于 while 或 for 语句时,导致退出程序循环。 +* **continue** 当 continue 语句用于 while 或 for 语句时,使程序循环移动到下一个迭代。 +* **next** 能能够导致读入下一个输入行,并返回到脚本的顶部。这可以避免对当前输入行执行其他的操作过程。 +* **exit** 语句使主输入循环退出并将控制转移到END,如果END存在的话。如果没有定义END规则,或在END中应用exit语句,则终止脚本的执行。 + +## 数组应用 + +数组是awk的灵魂,处理文本中最不能少的就是它的数组处理。因为数组索引(下标)可以是数字和字符串在awk中数组叫做关联数组(associative arrays)。awk 中的数组不必提前声明,也不必声明大小。数组元素用0或空字符串来初始化,这根据上下文而定。 + +### 数组的定义 + +数字做数组索引(下标): + +``` +Array[1]="sun" +Array[2]="kai" +``` + +字符串做数组索引(下标): + +``` +Array["first"]="www" +Array"[last"]="name" +Array["birth"]="1987" +``` + +使用中`print Array[1]`会打印出sun;使用`print Array[2]`会打印出kai;使用`print["birth"]`会得到1987。 + + **读取数组的值** + +``` +{ for(item in array) {print array[item]}; } #输出的顺序是随机的 +{ for(i=1;i<=len;i++) {print array[i]}; } #Len是数组的长度 +``` + +### 数组相关函数 + + **得到数组长度:** + +``` +awk 'BEGIN{info="it is a test";lens=split(info,tA," ");print length(tA),lens;}' +4 4 +``` + +length返回字符串以及数组长度,split进行分割字符串为数组,也会返回分割得到数组长度。 + +``` +awk 'BEGIN{info="it is a test";split(info,tA," ");print asort(tA);}' +4 +``` + +asort对数组进行排序,返回数组长度。 + + **输出数组内容(无序,有序输出):** + +``` +awk 'BEGIN{info="it is a test";split(info,tA," ");for(k in tA){print k,tA[k];}}' +4 test +1 it +2 is +3 a +``` + +`for…in`输出,因为数组是关联数组,默认是无序的。所以通过`for…in`得到是无序的数组。如果需要得到有序数组,需要通过下标获得。 + +``` +awk 'BEGIN{info="it is a test";tlen=split(info,tA," ");for(k=1;k<=tlen;k++){print k,tA[k];}}' +1 it +2 is +3 a +4 test +``` + +注意:数组下标是从1开始,与C数组不一样。 + + **判断键值存在以及删除键值:** + +``` +#错误的判断方法: +awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";if(tB["c"]!="1"){print "no found";};for(k in tB){print k,tB[k];}}' +no found +a a1 +b b1 +c +``` + +以上出现奇怪问题,`tB[“c”]`没有定义,但是循环时候,发现已经存在该键值,它的值为空,这里需要注意,awk数组是关联数组,只要通过数组引用它的key,就会自动创建改序列。 + +``` +#正确判断方法: +awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";if( "c" in tB){print "ok";};for(k in tB){print k,tB[k];}}' +a a1 +b b1 +``` + +`if(key in array)`通过这种方法判断数组中是否包含`key`键值。 + +``` +#删除键值: +[chengmo@localhost ~]$ awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";delete tB["a"];for(k in tB){print k,tB[k];}}' +b b1 +``` + +`delete array[key]`可以删除,对应数组`key`的,序列值。 + +### 二维、多维数组使用 + +awk的多维数组在本质上是一维数组,更确切一点,awk在存储上并不支持多维数组。awk提供了逻辑上模拟二维数组的访问方式。例如,`array[2,4]=1`这样的访问是允许的。awk使用一个特殊的字符串`SUBSEP(�34)`作为分割字段,在上面的例子中,关联数组array存储的键值实际上是2�344。 + +类似一维数组的成员测试,多维数组可以使用`if ( (i,j) in array)`这样的语法,但是下标必须放置在圆括号中。类似一维数组的循环访问,多维数组使用`for ( item in array )`这样的语法遍历数组。与一维数组不同的是,多维数组必须使用`split()`函数来访问单独的下标分量。 + +``` +awk 'BEGIN{ +for(i=1;i<=9;i++){ + for(j=1;j<=9;j++){ + tarr[i,j]=i*j; print i,"*",j,"=",tarr[i,j]; + } +} +}' +1 * 1 = 1 +1 * 2 = 2 +1 * 3 = 3 +1 * 4 = 4 +1 * 5 = 5 +1 * 6 = 6 +... +9 * 6 = 54 +9 * 7 = 63 +9 * 8 = 72 +9 * 9 = 81 +``` + +可以通过`array[k,k2]`引用获得数组内容。 + +另一种方法: + +``` +awk 'BEGIN{ +for(i=1;i<=9;i++){ + for(j=1;j<=9;j++){ + tarr[i,j]=i*j; + } +} +for(m in tarr){ + split(m,tarr2,SUBSEP); print tarr2[1],"*",tarr2[2],"=",tarr[m]; +} +}' +``` + +## 内置函数 + +awk内置函数,主要分以下3种类似:算数函数、字符串函数、其它一般函数、时间函数。 + +### 算术函数 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
格式描述
atan2( y, x )返回 y/x 的反正切。
cos( x )返回 x 的余弦;x 是弧度。
sin( x )返回 x 的正弦;x 是弧度。
exp( x )返回 x 幂函数。
log( x )返回 x 的自然对数。
sqrt( x )返回 x 平方根。
int( x )返回 x 的截断至整数的值。
rand( )返回任意数字 n,其中 0 <= n < 1。
srand( [expr] )将 rand 函数的种子值设置为 Expr 参数的值,或如果省略 Expr 参数则使用某天的时间。返回先前的种子值。
+ +举例说明: + +``` +awk 'BEGIN{OFMT="%.3f";fs=sin(1);fe=exp(10);fl=log(10);fi=int(3.1415);print fs,fe,fl,fi;}' +0.841 22026.466 2.303 3 + +``` + +OFMT 设置输出数据格式是保留3位小数。 + +获得随机数: + +``` +awk 'BEGIN{srand();fr=int(100*rand());print fr;}' +78 +awk 'BEGIN{srand();fr=int(100*rand());print fr;}' +31 +awk 'BEGIN{srand();fr=int(100*rand());print fr;}' +41 +``` + +### 字符串函数 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
格式描述
gsub( Ere, Repl, [ In ] )除了正则表达式所有具体值被替代这点,它和 sub 函数完全一样地执行。
sub( Ere, Repl, [ In ] )用 Repl 参数指定的字符串替换 In 参数指定的字符串中的由 Ere 参数指定的扩展正则表达式的第一个具体值。sub 函数返回替换的数量。出现在 Repl 参数指定的字符串中的 &(和符号)由 In 参数指定的与 Ere 参数的指定的扩展正则表达式匹配的字符串替换。如果未指定 In 参数,缺省值是整个记录($0 记录变量)。
index( String1, String2 )在由 String1 参数指定的字符串(其中有出现 String2 指定的参数)中,返回位置,从 1 开始编号。如果 String2 参数不在 String1 参数中出现,则返回 0(零)。
length [(String)]返回 String 参数指定的字符串的长度(字符形式)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。
blength [(String)]返回 String 参数指定的字符串的长度(以字节为单位)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。
substr( String, M, [ N ] )返回具有 N 参数指定的字符数量子串。子串从 String 参数指定的字符串取得,其字符以 M 参数指定的位置开始。M 参数指定为将 String 参数中的第一个字符作为编号 1。如果未指定 N 参数,则子串的长度将是 M 参数指定的位置到 String 参数的末尾 的长度。
match( String, Ere )在 String 参数指定的字符串(Ere 参数指定的扩展正则表达式出现在其中)中返回位置(字符形式),从 1 开始编号,或如果 Ere 参数不出现,则返回 0(零)。RSTART 特殊变量设置为返回值。RLENGTH 特殊变量设置为匹配的字符串的长度,或如果未找到任何匹配,则设置为 -1(负一)。
split( String, A, [Ere] )将 String 参数指定的参数分割为数组元素 A[1], A[2], . . ., A[n],并返回 n 变量的值。此分隔可以通过 Ere 参数指定的扩展正则表达式进行,或用当前字段分隔符(FS 特殊变量)来进行(如果没有给出 Ere 参数)。除非上下文指明特定的元素还应具有一个数字值,否则 A 数组中的元素用字符串值来创建。
tolower( String )返回 String 参数指定的字符串,字符串中每个大写字符将更改为小写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。
toupper( String )返回 String 参数指定的字符串,字符串中每个小写字符将更改为大写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。
sprintf(Format, Expr, Expr, . . . )根据 Format 参数指定的 printf 子例程格式字符串来格式化 Expr 参数指定的表达式并返回最后生成的字符串。
+ +注:Ere都可以是正则表达式。 + + **gsub,sub使用** + +``` +awk 'BEGIN{info="this is a test2010test!";gsub(/[0-9]+/,"!",info);print info}' +this is a test!test! +``` + +在 info中查找满足正则表达式,`/[0-9]+/` 用`””`替换,并且替换后的值,赋值给info 未给info值,默认是`$0` + + **查找字符串(index使用)** + +``` +awk 'BEGIN{info="this is a test2010test!";print index(info,"test")?"ok":"no found";}' +ok +``` + +未找到,返回0 + + **正则表达式匹配查找(match使用)** + +``` +awk 'BEGIN{info="this is a test2010test!";print match(info,/[0-9]+/)?"ok":"no found";}' +ok +``` + + **截取字符串(substr使用)** + +``` +[wangsl@centos5 ~]$ awk 'BEGIN{info="this is a test2010test!";print substr(info,4,10);}' +s is a tes +``` + +从第 4个 字符开始,截取10个长度字符串 + + **字符串分割(split使用)** + +``` +awk 'BEGIN{info="this is a test";split(info,tA," ");print length(tA);for(k in tA){print k,tA[k];}}' +4 +4 test +1 this +2 is +3 a +``` + +分割info,动态创建数组tA,这里比较有意思,`awk for …in`循环,是一个无序的循环。 并不是从数组下标1…n ,因此使用时候需要注意。 + + **格式化字符串输出(sprintf使用)** + +格式化字符串格式: + +其中格式化字符串包括两部分内容:一部分是正常字符,这些字符将按原样输出; 另一部分是格式化规定字符,以`"%"`开始,后跟一个或几个规定字符,用来确定输出内容格式。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
格式描述
%d十进制有符号整数
%u十进制无符号整数
%f浮点数
%s字符串
%c单个字符
%p指针的值
%e指数形式的浮点数
%x%X 无符号以十六进制表示的整数
%o无符号以八进制表示的整数
%g自动选择合适的表示法
+ +``` +awk 'BEGIN{n1=124.113;n2=-1.224;n3=1.2345; printf("%.2f,%.2u,%.2g,%X,%on",n1,n2,n3,n1,n1);}' +124.11,18446744073709551615,1.2,7C,174 +``` + +### 一般函数 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
格式描述
close( Expression )用同一个带字符串值的 Expression 参数来关闭由 print 或 printf 语句打开的或调用 getline 函数打开的文件或管道。如果文件或管道成功关闭,则返回 0;其它情况下返回非零值。如果打算写一个文件,并稍后在同一个程序中读取文件,则 close 语句是必需的。
system(command )执行 Command 参数指定的命令,并返回退出状态。等同于 system 子例程。
Expression | getline [ Variable ]从来自 Expression 参数指定的命令的输出中通过管道传送的流中读取一个输入记录,并将该记录的值指定给 Variable 参数指定的变量。如果当前未打开将 Expression 参数的值作为其命令名称的流,则创建流。创建的流等同于调用 popen 子例程,此时 Command 参数取 Expression 参数的值且 Mode 参数设置为一个是 r 的值。只要流保留打开且 Expression 参数求得同一个字符串,则对 getline 函数的每次后续调用读取另一个记录。如果未指定 Variable 参数,则 $0 记录变量和 NF 特殊变量设置为从流读取的记录。
getline [ Variable ] < Expression从 Expression 参数指定的文件读取输入的下一个记录,并将 Variable 参数指定的变量设置为该记录的值。只要流保留打开且 Expression 参数对同一个字符串求值,则对 getline 函数的每次后续调用读取另一个记录。如果未指定 Variable 参数,则 $0 记录变量和 NF 特殊变量设置为从流读取的记录。
getline [ Variable ]将 Variable 参数指定的变量设置为从当前输入文件读取的下一个输入记录。如果未指定 Variable 参数,则 $0 记录变量设置为该记录的值,还将设置 NF、NR 和 FNR 特殊变量。
+ + **打开外部文件(close用法)** + +``` +awk 'BEGIN{while("cat /etc/passwd"|getline){print $0;};close("/etc/passwd");}' +root:x:0:0:root:/root:/bin/bash +bin:x:1:1:bin:/bin:/sbin/nologin +daemon:x:2:2:daemon:/sbin:/sbin/nologin +``` + + **逐行读取外部文件(getline使用方法)** + +``` +awk 'BEGIN{while(getline < "/etc/passwd"){print $0;};close("/etc/passwd");}' +root:x:0:0:root:/root:/bin/bash +bin:x:1:1:bin:/bin:/sbin/nologin +daemon:x:2:2:daemon:/sbin:/sbin/nologin +``` + +``` +awk 'BEGIN{print "Enter your name:";getline name;print name;}' +Enter your name: +chengmo +chengmo +``` + + **调用外部应用程序(system使用方法)** + +``` +awk 'BEGIN{b=system("ls -al");print b;}' +total 42092 +drwxr-xr-x 14 chengmo chengmo 4096 09-30 17:47 . +drwxr-xr-x 95 root root 4096 10-08 14:01 .. +``` + +b返回值,是执行结果。 + +### 时间函数 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
格式描述
函数名说明
mktime( YYYY MM dd HH MM ss[ DST])生成时间格式
strftime([format [, timestamp]])格式化时间输出,将时间戳转为时间字符串 +具体格式,见下表.
systime()得到时间戳,返回从1970年1月1日开始到当前时间(不计闰年)的整秒数
+ + **建指定时间(mktime使用)** + +``` +awk 'BEGIN{tstamp=mktime("2001 01 01 12 12 12");print strftime("%c",tstamp);}' +2001年01月01日 星期一 12时12分12秒 +``` + +``` +awk 'BEGIN{tstamp1=mktime("2001 01 01 12 12 12");tstamp2=mktime("2001 02 01 0 0 0");print tstamp2-tstamp1;}' +2634468 +``` + +求2个时间段中间时间差,介绍了strftime使用方法 + +``` +awk 'BEGIN{tstamp1=mktime("2001 01 01 12 12 12");tstamp2=systime();print tstamp2-tstamp1;}' +308201392 +``` + + **strftime日期和时间格式说明符** + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
格式描述
%a星期几的缩写(Sun)
%A星期几的完整写法(Sunday)
%b月名的缩写(Oct)
%B月名的完整写法(October)
%c本地日期和时间
%d十进制日期
%D日期 08/20/99
%e日期,如果只有一位会补上一个空格
%H用十进制表示24小时格式的小时
%I用十进制表示12小时格式的小时
%j从1月1日起一年中的第几天
%m十进制表示的月份
%M十进制表示的分钟
%p12小时表示法(AM/PM)
%S十进制表示的秒
%U十进制表示的一年中的第几个星期(星期天作为一个星期的开始)
%w十进制表示的星期几(星期天是0)
%W十进制表示的一年中的第几个星期(星期一作为一个星期的开始)
%x重新设置本地日期(08/20/99)
%X重新设置本地时间(12:00:00)
%y两位数字表示的年(99)
%Y当前月份
%Z时区(PDT)
%%百分号(%)
+ + + \ No newline at end of file diff --git a/command/axel.md b/command/axel.md index f65daf6c2b..42591c657f 100644 --- a/command/axel.md +++ b/command/axel.md @@ -61,7 +61,7 @@ axel [options] url1 [url2] [url...] 如下载lnmp安装包指定10个线程,存到/tmp/: ``` -axel -n 10 -o /tmp/ http://www.linuxde.net/lnmp.tar.gz +axel -n 10 -o /tmp/ http://www.jsdig.com/lnmp.tar.gz ``` 如果下载过程中下载中断可以再执行下载命令即可恢复上次的下载进度。 diff --git a/command/chsh.md b/command/chsh.md index 853f49c93f..254494fb31 100644 --- a/command/chsh.md +++ b/command/chsh.md @@ -43,7 +43,7 @@ chsh(选项)(参数) 第二种: ``` -rocrocket@localhost ~ /etc/shells +[rocrocket@localhost ~]$ cat /etc/shells /bin/sh /bin/bash /sbin/nologin @@ -55,7 +55,7 @@ rocrocket@localhost ~ /etc/shells **查看当前正在使用的shell:** ``` -rocrocket@localhost ~ $SHELL +[rocrocket@localhost ~]$ echo $SHELL /bin/bash ``` @@ -74,7 +74,7 @@ Shell changed. 使用chsh加选项`-s`就可以修改登录的shell了!你会发现你现在执行`echo $SHELL`后仍然输出为`/bin/bash`,这是因为你需要重启你的shell才完全投入到zsh怀抱中去。`chsh -s`其实修改的就是`/etc/passwd`文件里和你的用户名相对应的那一行。现在来查看下: ``` -rocrocket@localhost ~ ^rocrocket +[rocrocket@localhost ~]$ cat /etc/passwd|grep ^rocrocket rocrocket:x:500:500:rocrocket,China:/rocrocket/PSB/home:/bin/zsh ``` diff --git a/command/clockdiff.md b/command/clockdiff.md new file mode 100644 index 0000000000..e01f16dae0 --- /dev/null +++ b/command/clockdiff.md @@ -0,0 +1,59 @@ +clockdiff +=== + +检测两台linux主机的时间差 + +## 补充说明 + +在ip报文的首部和ICMP报文的首部都可以放入时间戳数据。 **clockdiff** 程序正是使用时间戳来测算目的主机和本地主机的系统时间差。 + +### 选项 + +``` +-o:使用IP时间戳选项来测量系统时间差。时间戳只用3个。 +-o1:使用IP时间戳选项来测量系统时间差。用4个时间戳。如果-o和-o1都没有设置,那么就是用ICMP时间戳来测试系统时间差。 +``` + +### 实例 + +``` +lixi@lixi-desktop:~$ ping -T tsandaddr www.ustc.edu.cn -c 1 +PING www.ustc.edu.cn (202.38.64.9) 56(124) bytes of data. +64 bytes from 202.38.64.9: icmp_seq=1 ttl=62 time=0.823 ms +TS: lixi-desktop.local (210.45.74.25) 12522473 absolute + 210.45.74.1 -251 + local-gw.ustc.edu.cn (202.38.64.126) 248 + 202.38.64.9 -857514 +Unrecorded hops: 3 + +--- www.ustc.edu.cn ping statistics --- +1 packets transmitted, 1 received, 0% packet loss, time 0ms +rtt min/avg/max/mdev = 0.823/0.823/0.823/0.000 ms +``` + +首先由上面的得出在RRT不大的时候,几个ICMP时间戳的关系。本地主机和202.38.64.9之间的时间差约为:-857514+248-251=-857517。分别用-o(IP选项中时间戳)和不带选项(ICMP路由时间戳)上述路由的系统时间进行测试。得到的结果: + +``` +lixi@lixi-desktop:~# ./clockdiff -o 202.38.64.9 +.................................................. +host=202.38.64.9 rtt=1(0)ms/1ms delta=-857517ms/-857517ms Wed Dec 17 11:28:30 2008 +``` + +``` +lixi@lixi-desktop:~# ./clockdiff 202.38.64.9 +. +host=202.38.64.9 rtt=750(187)ms/0ms delta=-857517ms/-857517ms Wed Dec 17 11:28:35 2008 +``` + +两种方法测试的都比较准确。 + +``` +lixi@lixi-desktop:~#./clockdiff gigagate1.Princeton.EDU +.................................................. +host=gigagate1.Princeton.EDU rtt=307(21)ms/271ms delta=-5ms/-5ms Wed Dec 17 11:50:16 2008 +``` + +上面是测试一个RTT较大的目的主机和本地主机的系统时间差。不过在使用clockdiff的时候,需要一点运气,因为很多路由会忽略ICMP或IP时间戳。 + + + \ No newline at end of file diff --git a/command/comm.md b/command/comm.md index 9fbdfcfefa..8d4edc17eb 100644 --- a/command/comm.md +++ b/command/comm.md @@ -33,7 +33,7 @@ comm(选项)(参数) ### 实例 ``` -root@localhost text aaa.txt +[root@localhost text]# cat aaa.txt aaa bbb ccc @@ -86,7 +86,7 @@ ccc 打印出两个文件中不相同的行,需要删除第三列: ``` -root@localhost text 's/^\t//' +[root@localhost text]# comm aaa.txt bbb.txt -3 | sed 's/^\t//' aaa aaa ddd diff --git a/command/compress.md b/command/compress.md index bbdc131a99..25135f06d5 100644 --- a/command/compress.md +++ b/command/compress.md @@ -34,10 +34,10 @@ compress(选项)(参数) 将`/etc/man.config`复到`/tmp` ,并加以压缩 ``` -root@localhost ~ /tmp -root@localhost tmp /etc/man.config . +[root@localhost ~]# cd /tmp +[root@localhost tmp]# cp /etc/man.config . [root@localhost tmp]# compress man.config -root@localhost tmp -l +[root@localhost tmp]# ls -l ``` ``` diff --git a/command/csplit.md b/command/csplit.md index b71278d007..1daf6ab979 100644 --- a/command/csplit.md +++ b/command/csplit.md @@ -55,8 +55,8 @@ SERVER-3 需要将server.log分割成server1.log、server2.log、server3.log,这些文件的内容分别取自原文件中不同的SERVER部分: ``` -root@localhost split server00.log -root@localhost split +[root@localhost split]# csplit server.log /SERVER/ -n2 -s {*} -f server -b "%02d.log"; rm server00.log +[root@localhost split]# ls server01.log server02.log server03.log server.log ``` diff --git a/command/cupsenable.md b/command/cupsenable.md new file mode 100644 index 0000000000..2a94aabf1d --- /dev/null +++ b/command/cupsenable.md @@ -0,0 +1,30 @@ +cupsenable +=== + +启动指定的打印机 + +## 补充说明 + +**cupsenable命令** 用于启动指定的打印机。 + +### 语法 + +``` +cupsenable(选项)(参数) +``` + +### 选项 + +``` +-E:当连接到服务器时强制使用加密; +-U:指定连接服务器时使用的用户名; +-u:指定打印任务所属的用户; +-h:指定连接的服务器名和端口号; +``` + +### 参数 + +目标:指定目标打印机。 + + + \ No newline at end of file diff --git a/command/cut.md b/command/cut.md index dc1a99c2fc..0fb9e8e559 100644 --- a/command/cut.md +++ b/command/cut.md @@ -40,7 +40,7 @@ cut(选项)(参数) 例如有一个学生报表信息,包含No、Name、Mark、Percent: ``` -root@localhost text test.txt +[root@localhost text]# cat test.txt No Name Mark Percent 01 tom 69 91 02 jack 71 87 diff --git a/command/dd.md b/command/dd.md index 03f6cf4d66..3cd340ae9d 100644 --- a/command/dd.md +++ b/command/dd.md @@ -39,7 +39,7 @@ skip=<区块数>:一开始读取时,跳过指定的区块数; 1+0 records out 1048576 bytes (1.0 MB) copied, 0.006107 seconds, 172 MB/s -root@localhost text -sh sun.txt +[root@localhost text]# du -sh sun.txt 1.1M sun.txt ``` diff --git a/command/dig.md b/command/dig.md index 7d87d370d3..8f340d9373 100644 --- a/command/dig.md +++ b/command/dig.md @@ -37,24 +37,24 @@ dig(选项)(参数) ### 实例 ``` -[root@localhost ~]# dig www.linuxde.net +[root@localhost ~]# dig www.jsdig.com -; <<>> DiG 9.3.6-P1-RedHat-9.3.6-20.P1.el5_8.1 <<>> www.linuxde.net +; <<>> DiG 9.3.6-P1-RedHat-9.3.6-20.P1.el5_8.1 <<>> www.jsdig.com ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2115 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 0 ;; QUESTION SECTION: -;www.linuxde.net. IN A +;www.jsdig.com. IN A ;; ANSWER SECTION: -www.linuxde.net. 0 IN CNAME host.1.linuxde.net. -host.1.linuxde.net. 0 IN A 100.42.212.8 +www.jsdig.com. 0 IN CNAME host.1.jsdig.com. +host.1.jsdig.com. 0 IN A 100.42.212.8 ;; AUTHORITY SECTION: -linuxde.net. 8 IN NS f1g1ns2.dnspod.net. -linuxde.net. 8 IN NS f1g1ns1.dnspod.net. +jsdig.com. 8 IN NS f1g1ns2.dnspod.net. +jsdig.com. 8 IN NS f1g1ns1.dnspod.net. ;; Query time: 0 msec ;; SERVER: 202.96.104.15#53(202.96.104.15) diff --git a/command/dmesg.md b/command/dmesg.md index 1395c1b3f6..f11ad2f351 100644 --- a/command/dmesg.md +++ b/command/dmesg.md @@ -24,7 +24,7 @@ dmesg(选项) ### 实例 ``` -root@localhost ~ +[root@localhost ~]# dmesg | head Linux version 2.6.18-348.6.1.el5 (mockbuild@builder17.centos.org) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-54)) #1 SMP Tue May 21 15:34:22 EDT 2013 BIOS-provided physical RAM map: BIOS-e820: 0000000000010000 - 000000000009f400 (usable) diff --git a/command/dnf.md b/command/dnf.md new file mode 100644 index 0000000000..3caf6c990a --- /dev/null +++ b/command/dnf.md @@ -0,0 +1,326 @@ +dnf +=== + +新一代的RPM软件包管理器 + +## 补充说明 + +**DNF** 是新一代的rpm软件包管理器。他首先出现在 Fedora 18 这个发行版中。而最近,它取代了yum,正式成为 Fedora 22 的包管理器。 + +DNF包管理器克服了YUM包管理器的一些瓶颈,提升了包括用户体验,内存占用,依赖分析,运行速度等多方面的内容。DNF使用 RPM, libsolv 和 hawkey 库进行包管理操作。尽管它没有预装在 CentOS 和 RHEL 7 中,但你可以在使用 YUM 的同时使用 DNF 。你可以在这里获得关于 DNF 的更多知识:《 DNF 代替 YUM ,你所不知道的缘由》 + +DNF 的最新稳定发行版版本号是 1.0,发行日期是2015年5月11日。 这一版本的额 DNF 包管理器(包括在他之前的所有版本) 都大部分采用 Python 编写,发行许可为GPL v2. + +### 安装 DNF 包管理器 + +DNF 并未默认安装在 RHEL 或 CentOS 7系统中,但是 Fedora 22 已经默认使用 DNF . + +1、为了安装 DNF ,您必须先安装并启用 epel-release 依赖。 + +在系统中执行以下命令: + +``` +# yum install epel-release +``` + +或者 + +``` +# yum install epel-release -y +``` + +其实这里并没有强制使用”-y”的理由,相反的,在不使用”-y”的情况下,用户可以在安装过程中查看到底有哪些东西被安装进了系统。但对于没有这个需求的用户,您可以在 YUM 中使用”-y”参数来自动安装所有东西。 + +2、使用 epel-release 依赖中的 YUM 命令来安装 DNF 包。在系统中执行以下命令: + +``` +# yum install dnf +``` + +然后, DNF 包管理器就被成功的安装到你的系统中了。接下来,是时候开始我们的教程了!在这个教程中,您将会学到27个用于 DNF 包管理器的命令。使用这些命令,你可以方便有效的管理您系统中的 RPM 软件包。现在,让我们开始学习 DNF 包管理器的27条常用命令吧! + + **查看 DNF 包管理器版本** + +用处:该命令用于查看安装在您系统中的 DNF 包管理器的版本 + +``` +# dnf –version +``` + +!Check-DNF-Version + + **查看系统中可用的 DNF 软件库** + +用处:该命令用于显示系统中可用的 DNF 软件库 + +``` +# dnf repolist +``` + +!Check-All-Enabled-Repositories + + **查看系统中可用和不可用的所有的 DNF 软件库** + +用处:该命令用于显示系统中可用和不可用的所有的 DNF 软件库 + +``` +# dnf repolist all +``` + +!3 + + **列出所有 RPM 包** + +用处:该命令用于列出用户系统上的所有来自软件库的可用软件包和所有已经安装在系统上的软件包 + +``` +# dnf list +``` + +!4 + + **列出所有安装了的 RPM 包** + +用处:该命令用于列出所有安装了的 RPM 包 + +``` +# dnf list installed +``` + +!5 + + **列出所有可供安装的 RPM 包** + +用处:该命令用于列出来自所有可用软件库的可供安装的软件包 + +``` +# dnf list available +``` + +!6 + + **搜索软件库中的 RPM 包** + +用处:当你不知道你想要安装的软件的准确名称时,你可以用该命令来搜索软件包。你需要在”search”参数后面键入软件的部分名称来搜索。(在本例中我们使用”nano”) + +``` +# dnf search nano +``` + +!7 + + **查找某一文件的提供者** + +用处:当你想要查看是哪个软件包提供了系统中的某一文件时,你可以使用这条命令。(在本例中,我们将查找”/bin/bash”这个文件的提供者) + +``` +# dnf provides /bin/bash +``` + +!8 + + **查看软件包详情** + +用处:当你想在安装某一个软件包之前查看它的详细信息时,这条命令可以帮到你。(在本例中,我们将查看”nano”这一软件包的详细信息) + +``` +# dnf info nano +``` + +!9 + + **安装软件包** + +用处:使用该命令,系统将会自动安装对应的软件及其所需的所有依赖(在本例中,我们将用该命令安装nano软件) + +``` +# dnf install nano +``` + +!10 + + **升级软件包** + +用处:该命令用于升级制定软件包(在本例中,我们将用命令升级”systemd”这一软件包) + +``` +# dnf update systemd +``` + +!11 + + **检查系统软件包的更新** + +用处:该命令用于检查系统中所有软件包的更新 + +``` +# dnf check-update +``` + +!12 + + **升级所有系统软件包** + +用处:该命令用于升级系统中所有有可用升级的软件包 + +``` +# dnf update 或 # dnf upgrade +``` + +!13 + + **删除软件包** + +用处:删除系统中指定的软件包(在本例中我们将使用命令删除”nano”这一软件包) + +``` +# dnf remove nano 或 # dnf erase nano +``` + +!14 + + **删除无用孤立的软件包** + +用处:当没有软件再依赖它们时,某一些用于解决特定软件依赖的软件包将会变得没有存在的意义,该命令就是用来自动移除这些没用的孤立软件包。 + +``` +# dnf autoremove +``` + +!15 + + **删除缓存的无用软件包** + +用处:在使用 DNF 的过程中,会因为各种原因在系统中残留各种过时的文件和未完成的编译工程。我们可以使用该命令来删除这些没用的垃圾文件。 + +``` +# dnf clean all +``` + +!16 + + **获取有关某条命令的使用帮助** + +用处:该命令用于获取有关某条命令的使用帮助(包括可用于该命令的参数和该命令的用途说明)(本例中我们将使用命令获取有关命令”clean”的使用帮助) + +``` +# dnf help clean +``` + +!17 + + **查看所有的 DNF 命令及其用途** + +用处:该命令用于列出所有的 DNF 命令及其用途 + +``` +# dnf help +``` + +!18 + + **查看 DNF 命令的执行历史** + +用处:您可以使用该命令来查看您系统上 DNF 命令的执行历史。通过这个手段您可以知道在自您使用 DNF 开始有什么软件被安装和卸载。 + +``` +# dnf history +``` + +!19 + + **查看所有的软件包组** + +用处:该命令用于列出所有的软件包组 + +``` +# dnf grouplist +``` + +!20 + + **安装一个软件包组** + +用处:该命令用于安装一个软件包组(本例中,我们将用命令安装”Educational Software”这个软件包组) + +``` +# dnf groupinstall ‘Educational Software’ +``` + +!21 + + **升级一个软件包组中的软件包** + +用处:该命令用于升级一个软件包组中的软件包(本例中,我们将用命令升级”Educational Software”这个软件包组中的软件) + +``` +# dnf groupupdate ‘Educational Software’ +``` + +!22 + + **删除一个软件包组** + +用处:该命令用于删除一个软件包组(本例中,我们将用命令删除”Educational Software”这个软件包组) + +``` +# dnf groupremove ‘Educational Software’ +``` + +!23 + + **从特定的软件包库安装特定的软件** + +用处:该命令用于从特定的软件包库安装特定的软件(本例中我们将使用命令从软件包库 epel 中安装 phpmyadmin 软件包) + +``` +# dnf –enablerepo=epel install phpmyadmin +``` + + **更新软件包到最新的稳定发行版** + +用处:该命令可以通过所有可用的软件源将已经安装的所有软件包更新到最新的稳定发行版 + +``` +# dnf distro-sync +``` + + **重新安装特定软件包** + +用处:该命令用于重新安装特定软件包(本例中,我们将使用命令重新安装”nano”这个软件包) + +``` +# dnf reinstall nano +``` + +!26 + + **回滚某个特定软件的版本** + +用处:该命令用于降低特定软件包的版本(如果可能的话)(本例中,我们将使用命令降低”acpid”这个软件包的版本) + +``` +# dnf downgrade acpid +``` + +样例输出: + +``` +Using metadata from Wed May 20 12:44:59 2015 +No match for available package: acpid-2.0.19-5.el7.x86_64 +Error: Nothing to do. +``` + +原作者注:在执行这条命令的时候, DNF 并没有按照我期望的那样降级指定的软件(“acpid”)。该问题已经上报。 + +### 总结 + +DNF 包管理器作为 YUM 包管理器的升级替代品,它能自动完成更多的操作。但在我看来,正因如此,所以 DNF 包管理器不会太受那些经验老道的 Linux 系统管理者的欢迎。举例如下: + +1. 在 DNF 中没有 –skip-broken 命令,并且没有替代命令供选择。 +2. 在 DNF 中没有判断哪个包提供了指定依赖的 resolvedep 命令。 +3. 在 DNF 中没有用来列出某个软件依赖包的 deplist 命令。 +4. 当你在 DNF 中排除了某个软件库,那么该操作将会影响到你之后所有的操作,不像在 YUM 下那样,你的排除操作只会咋升级和安装软件时才起作用。 + + + \ No newline at end of file diff --git a/command/domainname.md b/command/domainname.md index a752cd79aa..58a9b2cead 100644 --- a/command/domainname.md +++ b/command/domainname.md @@ -31,11 +31,11 @@ NIS域名:指定要设置的NIS域名。 getdomainname()=`(none)' (none) [root@AY1307311912260196fcZ ~]# domainname -www.linuxde.net +www.jsdig.com [root@AY1307311912260196fcZ ~]# domainname -v -getdomainname()=`www.linuxde.net' -www.linuxde.net +getdomainname()=`www.jsdig.com' +www.jsdig.com ``` diff --git a/command/dpkg-reconfigure.md b/command/dpkg-reconfigure.md new file mode 100644 index 0000000000..145887d145 --- /dev/null +++ b/command/dpkg-reconfigure.md @@ -0,0 +1,45 @@ +dpkg-reconfigure +=== + +Debian Linux中重新配制一个已经安装的软件包 + +## 补充说明 + +**dpkg-reconfigure命令** 是Debian Linux中重新配置已经安装过的软件包,可以将一个或者多个已安装的软件包传递给此指令,它将询问软件初次安装后的配置问题。 + +当用户需要再次对软件包配置的时候,可以使用dpkg-reconfigure命令来对指定的软件包进行配置。 + +### 语法 + +``` +dpkg-reconfigure(选项)(参数) +``` + +### 选项 + +``` +-a:重新配置所有的软件包; +-u或--unseen-only:仅显示未提过的问题; +--default-priority:使用默认优先级,而非“低”级; +--force:强制执行操作,需谨慎使用此选项; +--no-reload:不要轻易的重装模板(使用时请慎重考虑); +-f或--frontend:指定 debconf 前端界面; +-p或--priority:指定要显示的问题的最优先级; +--terse:开启简要模式。 + +``` + +### 参数 + +软件包名:需要重新配置的已安装的软件包。 + +### 实例 + +用于配置语言: + +``` +sudo dpkg-reconfigure locales +``` + + + \ No newline at end of file diff --git a/command/dpkg.md b/command/dpkg.md new file mode 100644 index 0000000000..3261fc00c8 --- /dev/null +++ b/command/dpkg.md @@ -0,0 +1,49 @@ +dpkg +=== + +Debian Linux系统上安装、创建和管理软件包 + +## 补充说明 + +**dpkg命令** 是Debian Linux系统用来安装、创建和管理软件包的实用工具。 + +### 语法 + +``` +dpkg(选项)(参数) +``` + +### 选项 + +``` +-i:安装软件包; +-r:删除软件包; +-P:删除软件包的同时删除其配置文件; +-L:显示于软件包关联的文件; +-l:显示已安装软件包列表; +--unpack:解开软件包; +-c:显示软件包内文件列表; +--confiugre:配置软件包。 +``` + +### 参数 + +Deb软件包:指定要操作的.deb软件包。 + +### 实例 + +``` +dpkg -i package.deb #安装包 +dpkg -r package #删除包 +dpkg -P package #删除包(包括配置文件) +dpkg -L package #列出与该包关联的文件 +dpkg -l package #显示该包的版本 +dpkg --unpack package.deb #解开deb包的内容 +dpkg -S keyword #搜索所属的包内容 +dpkg -l #列出当前已安装的包 +dpkg -c package.deb #列出deb包的内容 +dpkg --configure package #配置包 +``` + + + \ No newline at end of file diff --git a/command/du.md b/command/du.md index 494c18d09e..6981b1494d 100644 --- a/command/du.md +++ b/command/du.md @@ -79,7 +79,7 @@ root@localhost [test]# du 显示多个文件所占空间: ``` -root@localhost test.gz log31.tar.gz +[root@localhost test]# du log30.tar.gz log31.tar.gz 4 log30.tar.gz 4 log31.tar.gz ``` @@ -93,7 +93,7 @@ root@localhost test.gz log31.tar.gz [root@localhost test]# du -s scf 32 scf -root@localhost test .. +[root@localhost test]# cd .. [root@localhost soft]# du -s test 1288 test ``` diff --git a/command/enable.md b/command/enable.md index 93d032c5d4..1c29175820 100644 --- a/command/enable.md +++ b/command/enable.md @@ -35,7 +35,6 @@ enable(选项)(参数) [root@localhost ~]# enable -a enable . enable : -enable [ enable alias enable bg enable bind diff --git a/command/expr.md b/command/expr.md new file mode 100644 index 0000000000..04224a072a --- /dev/null +++ b/command/expr.md @@ -0,0 +1,43 @@ +expr +=== + +一款表达式计算工具 + +## 补充说明 + +**expr命令** 是一款表达式计算工具,使用它完成表达式的求值操作。 + +expr的常用运算符: + +* 加法运算:+ +* 减法运算:- +* 乘法运算:\* +* 除法运算:/ +* 求摸(取余)运算:% + +### 语法 + +``` +expr(选项)(参数) +``` + +### 选项 + +``` +--help:显示指令的帮助信息; +--version:显示指令版本信息。 +``` + +### 参数 + +表达式:要求值的表达式。 + +### 实例 + +``` +result=`expr 2 + 3` +result=$(expr $no1 + 5) +``` + + + \ No newline at end of file diff --git a/command/fdisk.md b/command/fdisk.md index 418303c7bb..bfb6e6d896 100644 --- a/command/fdisk.md +++ b/command/fdisk.md @@ -225,7 +225,7 @@ Syncing disks. 在sdb1上建立ext2分区: ``` -root@localhost ~.ext2 /dev/sdb1 +[root@localhost ~]# mkfs.ext2 /dev/sdb1 mke2fs 1.39 (29-May-2006) Filesystem label= OS type: Linux @@ -279,16 +279,16 @@ This filesystem will be automatically checked every 32 mounts or 建立两个目录`/oracle`和`/web`,将新建好的两个分区挂载到系统: ``` -root@localhost ~ /oracle +[root@localhost ~]# mkdir /oracle [root@localhost ~]# mkdir /web -root@localhost ~ /dev/sdb1 /oracle +[root@localhost ~]# mount /dev/sdb1 /oracle [root@localhost ~]# mount /dev/sdb6 /web ``` 查看分区挂载情况: ``` -root@localhost ~ -h +[root@localhost ~]# df -h 文件系统 容量 已用 可用 已用% 挂载点 /dev/mapper/VolGroup00-LogVol00 6.7G 2.8G 3.6G 44% / diff --git a/command/file.md b/command/file.md index f567cdd1a5..207c046286 100644 --- a/command/file.md +++ b/command/file.md @@ -34,7 +34,7 @@ file(选项)(参数) 显示文件类型 ``` -root@localhost ~.log +[root@localhost ~]# file install.log install.log: UTF-8 Unicode text [root@localhost ~]# file -b install.log <== 不显示文件名称 @@ -51,7 +51,7 @@ text/plain; charset=utf-8 显示符号链接的文件类型 ``` -root@localhost ~ -l /var/mail +[root@localhost ~]# ls -l /var/mail lrwxrwxrwx 1 root root 10 08-13 00:11 /var/mail -> spool/mail [root@localhost ~]# file /var/mail diff --git a/command/ftp.md b/command/ftp.md index 1ba39fdf2b..4d0f578840 100644 --- a/command/ftp.md +++ b/command/ftp.md @@ -40,7 +40,7 @@ FTP>cdup: 返回上一级目录. FTP>chmod: 改变远端主机的文件权限. FTP>close: 终止远端的FTP进程,返回到FTP命令状态, 所有的宏定义都被删除. FTP>delete: 删除远端主机中的文件. -FTP>dir remote-directory] 列出当前远端主机目录中的文件.如果有本地文件,就将结果写至本地文件. +FTP>dir [remote-directory] local-[file] 列出当前远端主机目录中的文件.如果有本地文件,就将结果写至本地文件. FTP>get [remote-file] [local-file] 从远端主机中传送至本地主机中. FTP>help [command] 输出命令的解释. FTP>lcd: 改变当前本地主机的工作目录,如果缺省,就转到当前用户的HOME目录. diff --git a/command/gcc.md b/command/gcc.md new file mode 100644 index 0000000000..b266399e07 --- /dev/null +++ b/command/gcc.md @@ -0,0 +1,117 @@ +gcc +=== + +基于C/C++的编译器 + +## 补充说明 + +**gcc命令** 使用GNU推出的基于C/C++的编译器,是开放源代码领域应用最广泛的编译器,具有功能强大,编译代码支持性能优化等特点。现在很多程序员都应用GCC,怎样才能更好的应用GCC。目前,GCC可以用来编译C/C++、FORTRAN、JAVA、OBJC、ADA等语言的程序,可根据需要选择安装支持的语言。 + +### 语法 + +``` +gcc(选项)(参数) +``` + +### 选项 + +``` +-o:指定生成的输出文件; +-E:仅执行编译预处理; +-S:将C代码转换为汇编代码; +-wall:显示警告信息; +-c:仅执行编译操作,不进行连接操作。 +``` + +### 参数 + +C源文件:指定C语言源代码文件。 + +### 实例 + + **常用编译命令选项** + +假设源程序文件名为test.c + + **无选项编译链接** + +``` +gcc test.c +``` + +将test.c预处理、汇编、编译并链接形成可执行文件。这里未指定输出文件,默认输出为a.out。 + + **选项 -o** + +``` +gcc test.c -o test +``` + +将test.c预处理、汇编、编译并链接形成可执行文件test。-o选项用来指定输出文件的文件名。 + + **选项 -E** + +``` +gcc -E test.c -o test.i +``` + +将test.c预处理输出test.i文件。 + + **选项 -S** + +``` +gcc -S test.i +``` + +将预处理输出文件test.i汇编成test.s文件。 + + **选项 -c** + +``` +gcc -c test.s +``` + +将汇编输出文件test.s编译输出test.o文件。 + + **无选项链接** + +``` +gcc test.o -o test +``` + +将编译输出文件test.o链接成最终可执行文件test。 + + **选项 -O** + +``` +gcc -O1 test.c -o test +``` + +使用编译优化级别1编译程序。级别为1~3,级别越大优化效果越好,但编译时间越长。 + + **多源文件的编译方法** + +如果有多个源文件,基本上有两种编译方法: + +假设有两个源文件为test.c和testfun.c + + **多个文件一起编译** + +``` +gcc testfun.c test.c -o test +``` + +将testfun.c和test.c分别编译后链接成test可执行文件。 + + **分别编译各个源文件,之后对编译后输出的目标文件链接。** + +``` +gcc -c testfun.c #将testfun.c编译成testfun.o +gcc -c test.c #将test.c编译成test.o +gcc -o testfun.o test.o -o test #将testfun.o和test.o链接成test +``` + +以上两种方法相比较,第一中方法编译时需要所有文件重新编译,而第二种方法可以只重新编译修改的文件,未修改的文件不用重新编译。 + + + \ No newline at end of file diff --git a/command/gdb.md b/command/gdb.md new file mode 100644 index 0000000000..52a6d0e859 --- /dev/null +++ b/command/gdb.md @@ -0,0 +1,461 @@ +gdb +=== + +功能强大的程序调试器 + +## 补充说明 + +**gdb命令** 包含在GNU的gcc开发套件中,是功能强大的程序调试器。GDB中的命令固然很多,但我们只需掌握其中十个左右的命令,就大致可以完成日常的基本的程序调试工作。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令解释示例
file <文件名>加载被调试的可执行程序文件。 +因为一般都在被调试程序所在目录下执行GDB,因而文本名不需要带路径。(gdb) file gdb-sample
rRun的简写,运行被调试的程序。 +如果此前没有下过断点,则执行完整个程序;如果有断点,则程序暂停在第一个可用断点处。(gdb) r
cContinue的简写,继续执行被调试程序,直至下一个断点或程序结束。(gdb) c
b <行号> +b <函数名称> +b *<函数名称> +b *<代码地址> d [编号]b: Breakpoint的简写,设置断点。两可以使用“行号”“函数名称”“执行地址”等方式指定断点位置。 +其中在函数名称前面加“*”符号表示将断点设置在“由编译器生成的prolog代码处”。如果不了解汇编,可以不予理会此用法。 d: Delete breakpoint的简写,删除指定编号的某个断点,或删除所有断点。断点编号从1开始递增。(gdb) b 8 +(gdb) b main +(gdb) b *main +(gdb) b *0x804835c (gdb) d
s, ns: 执行一行源程序代码,如果此行代码中有函数调用,则进入该函数; +n: 执行一行源程序代码,此行代码中的函数调用也一并执行。 s 相当于其它调试器中的“Step Into (单步跟踪进入)”; +n 相当于其它调试器中的“Step Over (单步跟踪)”。 这两个命令必须在有源代码调试信息的情况下才可以使用(GCC编译时使用“-g”参数)。(gdb) s +(gdb) n
si, nisi命令类似于s命令,ni命令类似于n命令。所不同的是,这两个命令(si/ni)所针对的是汇编指令,而s/n针对的是源代码。(gdb) si +(gdb) ni
p <变量名称>Print的简写,显示指定变量(临时变量或全局变量)的值。(gdb) p i +(gdb) p nGlobalVar
display ... undisplay <编号>display,设置程序中断后欲显示的数据及其格式。 +例如,如果希望每次程序中断后可以看到即将被执行的下一条汇编指令,可以使用命令 +“display /i $pc” +其中 $pc 代表当前汇编指令,/i 表示以十六进行显示。当需要关心汇编代码时,此命令相当有用。 undispaly,取消先前的display设置,编号从1开始递增。(gdb) display /i $pc (gdb) undisplay 1
iinfo的简写,用于显示各类信息,详情请查阅“help i”。(gdb) i r
qQuit的简写,退出GDB调试环境。(gdb) q
help [命令名称]GDB帮助命令,提供对GDB名种命令的解释说明。 +如果指定了“命令名称”参数,则显示该命令的详细说明;如果没有指定参数,则分类显示所有GDB命令,供用户进一步浏览和查询。(gdb) help
+ +### 语法 + +``` +gdb(选项)(参数) +``` + +### 选项 + +``` +-cd:设置工作目录; +-q:安静模式,不打印介绍信息和版本信息; +-d:添加文件查找路径; +-x:从指定文件中执行GDB指令; +-s:设置读取的符号表文件。 +``` + +### 参数 + +文件:二进制可执行程序。 + +### 实例 + +以下是linux下dgb调试的一个实例,先给出一个示例用的小程序,C语言代码: + +``` +#include +int nGlobalVar = 0; + +int tempFunction(int a, int b) +{ + printf("tempFunction is called, a = %d, b = %d /n", a, b); + return (a + b); +} + +int main() +{ + int n; + n = 1; + n++; + n--; + + nGlobalVar += 100; + nGlobalVar -= 12; + + printf("n = %d, nGlobalVar = %d /n", n, nGlobalVar); + + n = tempFunction(1, 2); + printf("n = %d", n); + + return 0; +} +``` + +请将此代码复制出来并保存到文件 gdb-sample.c 中,然后切换到此文件所在目录,用GCC编译之: + +``` +gcc gdb-sample.c -o gdb-sample -g +``` + +在上面的命令行中,使用 -o 参数指定了编译生成的可执行文件名为 gdb-sample,使用参数 -g 表示将源代码信息编译到可执行文件中。如果不使用参数 -g,会给后面的GDB调试造成不便。当然,如果我们没有程序的源代码,自然也无从使用 -g 参数,调试/跟踪时也只能是汇编代码级别的调试/跟踪。 + +下面“gdb”命令启动GDB,将首先显示GDB说明,不管它: + +``` +GNU gdb Red Hat Linux (5.3post-0.20021129.18rh) +Copyright 2003 free Software Foundation, Inc. +GDB is free software, covered by the GNU General Public License, and you are +welcome to change it and/or distribute copies of it under certain conditions. +type "show copying" to see the conditions. +There is absolutely no warranty for GDB. Type "show warranty" for details. +This GDB was configured as "i386-redhat-linux-gnu". +(gdb) +``` + +上面最后一行“(gdb)”为GDB内部命令引导符,等待用户输入GDB命令。 + +下面使用“file”命令载入被调试程序 gdb-sample(这里的 gdb-sample 即前面 GCC 编译输出的可执行文件): + +``` +(gdb) file gdb-sample +Reading symbols from gdb-sample...done. +``` + +上面最后一行提示已经加载成功。 + +下面使用“r”命令执行(Run)被调试文件,因为尚未设置任何断点,将直接执行到程序结束: + +``` +(gdb) r +Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample +n = 1, nGlobalVar = 88 +tempFunction is called, a = 1, b = 2 +n = 3 +Program exited normally. +``` + +下面使用“b”命令在 main 函数开头设置一个断点(Breakpoint): + +``` +(gdb) b main +Breakpoint 1 at 0x804835c: file gdb-sample.c, line 19. +``` + +上面最后一行提示已经成功设置断点,并给出了该断点信息:在源文件 gdb-sample.c 第19行处设置断点;这是本程序的第一个断点(序号为1);断点处的代码地址为 0x804835c(此值可能仅在本次调试过程中有效)。回过头去看源代码,第19行中的代码为“n = 1”,恰好是 main 函数中的第一个可执行语句(前面的“int n;”为变量定义语句,并非可执行语句)。 + +再次使用“r”命令执行(Run)被调试程序: + +``` +(gdb) r +Starting program: /home/liigo/temp/gdb-sample + +Breakpoint 1, main () at gdb-sample.c:19 +19 n = 1; +``` + +程序中断在gdb-sample.c第19行处,即main函数是第一个可执行语句处。 + +上面最后一行信息为:下一条将要执行的源代码为“n = 1;”,它是源代码文件gdb-sample.c中的第19行。 + +下面使用“s”命令(Step)执行下一行代码(即第19行“n = 1;”): + +``` +(gdb) s +20 n++; +``` + +上面的信息表示已经执行完“n = 1;”,并显示下一条要执行的代码为第20行的“n++;”。 + +既然已经执行了“n = 1;”,即给变量 n 赋值为 1,那我们用“p”命令(Print)看一下变量 n 的值是不是 1 : + +``` +(gdb) p n +$1 = 1 +``` + +果然是 1。($1大致是表示这是第一次使用“p”命令——再次执行“p n”将显示“$2 = 1”——此信息应该没有什么用处。) + +下面我们分别在第26行、tempFunction 函数开头各设置一个断点(分别使用命令“b 26”“b tempFunction”): + +``` +(gdb) b 26 +Breakpoint 2 at 0x804837b: file gdb-sample.c, line 26. +(gdb) b tempFunction +Breakpoint 3 at 0x804832e: file gdb-sample.c, line 12. +``` + +使用“c”命令继续(Continue)执行被调试程序,程序将中断在第二 个断点(26行),此时全局变量 nGlobalVar 的值应该是 88;再一次执行“c”命令,程序将中断于第三个断点(12行,tempFunction 函数开头处),此时tempFunction 函数的两个参数 a、b 的值应分别是 1 和 2: + +``` +(gdb) c +Continuing. + +Breakpoint 2, main () at gdb-sample.c:26 +26 printf("n = %d, nGlobalVar = %d /n", n, nGlobalVar); +(gdb) p nGlobalVar +$2 = 88 +(gdb) c +Continuing. +n = 1, nGlobalVar = 88 + +Breakpoint 3, tempFunction (a=1, b=2) at gdb-sample.c:12 +12 printf("tempFunction is called, a = %d, b = %d /n", a, b); +(gdb) p a +$3 = 1 +(gdb) p b +$4 = 2 +``` + +上面反馈的信息一切都在我们预料之中~~ + +再一次执行“c”命令(Continue),因为后面再也没有其它断点,程序将一直执行到结束: + +``` +(gdb) c +Continuing. +tempFunction is called, a = 1, b = 2 +n = 3 +Program exited normally. +``` + +有时候需要看到编译器生成的汇编代码,以进行汇编级的调试或跟踪,又该如何操作呢? + +这就要用到display命令“display /i $pc”了(此命令前面已有详细解释): + +``` +(gdb) display /i $pc +(gdb) +``` + +此后程序再中断时,就可以显示出汇编代码了: + +``` +(gdb) r +Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample + +Breakpoint 1, main () at gdb-sample.c:19 +19 n = 1; +1: x/i $pc 0x804835c : movl $0x1,0xfffffffc(%ebp) +``` + +看到了汇编代码,“n = 1;”对应的汇编代码是“movl $0x1,0xfffffffc(%ebp)”。 + +并且以后程序每次中断都将显示下一条汇编指定(“si”命令用于执行一条汇编代码——区别于“s”执行一行C代码): + +``` +(gdb) si +20 n++; +1: x/i $pc 0x8048363 : lea 0xfffffffc(%ebp),%eax +(gdb) si +0x08048366 20 n++; +1: x/i $pc 0x8048366 : incl (%eax) +(gdb) si +21 n--; +1: x/i $pc 0x8048368 : lea 0xfffffffc(%ebp),%eax +(gdb) si +0x0804836b 21 n--; +1: x/i $pc 0x804836b : decl (%eax) +(gdb) si +23 nGlobalVar += 100; +1: x/i $pc 0x804836d : addl $0x64,0x80494fc +``` + +接下来我们试一下命令“b *<函数名称>”。 + +为了更简明,有必要先删除目前所有断点(使用“d”命令——Delete breakpoint): + +``` +(gdb) d +Delete all breakpoints? (y or n) y +(gdb) +``` + +当被询问是否删除所有断点时,输入“y”并按回车键即可。 + +下面使用命令“b *main”在 main 函数的 prolog 代码处设置断点(prolog、epilog,分别表示编译器在每个函数的开头和结尾自行插入的代码): + +``` +(gdb) b *main +Breakpoint 4 at 0x804834c: file gdb-sample.c, line 17. +(gdb) r +The program being debugged has been started already. +Start it from the beginning? (y or n) y +Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample + +Breakpoint 4, main () at gdb-sample.c:17 +17 { +1: x/i $pc 0x804834c
: push %ebp +(gdb) si +0x0804834d 17 { +1: x/i $pc 0x804834d : mov %esp,%ebp +(gdb) si +0x0804834f in main () at gdb-sample.c:17 +17 { +1: x/i $pc 0x804834f : sub $0x8,%esp +(gdb) si +0x08048352 17 { +1: x/i $pc 0x8048352 : and $0xfffffff0,%esp +(gdb) si +0x08048355 17 { +1: x/i $pc 0x8048355 : mov $0x0,%eax +(gdb) si +0x0804835a 17 { +1: x/i $pc 0x804835a : sub %eax,%esp +(gdb) si +19 n = 1; +1: x/i $pc 0x804835c : movl $0x1,0xfffffffc(%ebp) +``` + +此时可以使用“i r”命令显示寄存器中的当前值———“i r”即“Infomation Register”: + +``` +(gdb) i r +eax 0xbffff6a4 -1073744220 +ecx 0x42015554 1107383636 +edx 0x40016bc8 1073834952 +ebx 0x42130a14 1108544020 +esp 0xbffff6a0 0xbffff6a0 +ebp 0xbffff6a8 0xbffff6a8 +esi 0x40015360 1073828704 +edi 0x80483f0 134513648 +eip 0x8048366 0x8048366 +eflags 0x386 902 +cs 0x23 35 +ss 0x2b 43 +ds 0x2b 43 +es 0x2b 43 +fs 0x0 0 +gs 0x33 51 +``` + +当然也可以显示任意一个指定的寄存器值: + +``` +(gdb) i r eax +eax 0xbffff6a4 -1073744220 +``` + +最后一个要介绍的命令是“q”,退出(Quit)GDB调试环境: + +``` +(gdb) q +The program is running. exit anyway? (y or n) +``` + + + \ No newline at end of file diff --git a/command/htpasswd.md b/command/htpasswd.md index c3100f785b..6f6057606a 100644 --- a/command/htpasswd.md +++ b/command/htpasswd.md @@ -34,10 +34,10 @@ apache服务器创建密码认证文件 **利用htpasswd命令添加用户** ``` -htpasswd -bc .passwd www.linuxde.net php +htpasswd -bc .passwd www.jsdig.com php ``` -在bin目录下生成一个.passwd文件,用户名www.linuxde.net,密码:php,默认采用MD5加密方式。 +在bin目录下生成一个.passwd文件,用户名www.jsdig.com,密码:php,默认采用MD5加密方式。 **在原有密码文件中增加下一个用户** diff --git a/command/id.md b/command/id.md index 911710c8c9..567be5fa30 100644 --- a/command/id.md +++ b/command/id.md @@ -12,7 +12,7 @@ id ### 语法 ``` -id -gGnru][--version][用户名称] +id [-gGnru]--[help][--version][用户名称] ``` ### 选项 diff --git a/command/insmod.md b/command/insmod.md index 0424866745..0af2924f7b 100644 --- a/command/insmod.md +++ b/command/insmod.md @@ -39,7 +39,7 @@ insmod(选项)(参数) [root@localhost boot]# insmod /lib/modules/2.6. 18-8.el5/kernel/drivers/md/raid1.ko -root@localhost boot | grep raid1 +[root@localhost boot]# lsmod | grep raid1 raid1 25153 0 ``` diff --git a/command/ldconfig.md b/command/ldconfig.md new file mode 100644 index 0000000000..c9b75b75a8 --- /dev/null +++ b/command/ldconfig.md @@ -0,0 +1,46 @@ +ldconfig +=== + +动态链接库管理命令 + +## 补充说明 + +**ldconfig命令** 的用途主要是在默认搜寻目录`/lib`和`/usr/lib`以及动态库配置文件`/etc/ld.so.conf`内所列的目录下,搜索出可共享的动态链接库(格式如lib*.so*),进而创建出动态装入程序(ld.so)所需的连接和缓存文件。缓存文件默认为`/etc/ld.so.cache`,此文件保存已排好序的动态链接库名字列表,为了让动态链接库为系统所共享,需运行动态链接库的管理命令ldconfig,此执行程序存放在`/sbin`目录下。 + +ldconfig通常在系统启动时运行,而当用户安装了一个新的动态链接库时,就需要手工运行这个命令。 + +### 语法 + +``` +ldconfig [-v|--verbose] [-n] [-N] [-X] [-f CONF] [-C CACHE] [-r ROOT] [-l] [-p|--print-cache] [-c FORMAT] [--format=FORMAT] [-V] -?|--[help|--usage] path... +``` + +### 选项 + +``` +-v或--verbose:用此选项时,ldconfig将显示正在扫描的目录及搜索到的动态链接库,还有它所创建的连接的名字。 +-n:用此选项时,ldconfig仅扫描命令行指定的目录,不扫描默认目录(/lib、/usr/lib),也不扫描配置文件/etc/ld.so.conf所列的目录。 +-N:此选项指示ldconfig不重建缓存文件(/etc/ld.so.cache),若未用-X选项,ldconfig照常更新文件的连接。 +-X:此选项指示ldconfig不更新文件的连接,若未用-N选项,则缓存文件正常更新。 +-f CONF:此选项指定动态链接库的配置文件为CONF,系统默认为/etc/ld.so.conf。 +-C CACHE:此选项指定生成的缓存文件为CACHE,系统默认的是/etc/ld.so.cache,此文件存放已排好序的可共享的动态链接库的列表。 +-r ROOT:此选项改变应用程序的根目录为ROOT(是调用chroot函数实现的)。选择此项时,系统默认的配置文件/etc/ld.so.conf,实际对应的为ROOT/etc/ld.so.conf。如用-r /usr/zzz时,打开配置文件/etc/ld.so.conf时,实际打开的是/usr/zzz/etc/ld.so.conf文件。用此选项,可以大大增加动态链接库管理的灵活性。 +-l:通常情况下,ldconfig搜索动态链接库时将自动建立动态链接库的连接,选择此项时,将进入专家模式,需要手工设置连接,一般用户不用此项。 +-p或--print-cache:此选项指示ldconfig打印出当前缓存文件所保存的所有共享库的名字。 +-c FORMAT 或 --format=FORMAT:此选项用于指定缓存文件所使用的格式,共有三种:old(老格式),new(新格式)和compat(兼容格式,此为默认格式)。 +-V:此选项打印出ldconfig的版本信息,而后退出。 +-? 或 --help 或 --usage:这三个选项作用相同,都是让ldconfig打印出其帮助信息,而后退出。 +``` + + **ldconfig几个需要注意的地方:** + +1. 往`/lib`和`/usr/lib`里面加东西,是不用修改`/etc/ld.so.conf`的,但是完了之后要调一下ldconfig,不然这个library会找不到。 +2. 想往上面两个目录以外加东西的时候,一定要修改`/etc/ld.so.conf`,然后再调用ldconfig,不然也会找不到。 +3. 比如安装了一个mysql到`/usr/local/mysql`,mysql有一大堆library在`/usr/local/mysql/lib`下面,这时就需要在`/etc/ld.so.conf`下面加一行`/usr/local/mysql/lib`,保存过后ldconfig一下,新的library才能在程序运行时被找到。 +4. 如果想在这两个目录以外放lib,但是又不想在`/etc/ld.so.conf`中加东西(或者是没有权限加东西)。那也可以,就是export一个全局变量LD_LIBRARY_PATH,然后运行程序的时候就会去这个目录中找library。一般来讲这只是一种临时的解决方案,在没有权限或临时需要的时候使用。 +5. ldconfig做的这些东西都与运行程序时有关,跟编译时一点关系都没有。编译的时候还是该加-L就得加,不要混淆了。 +6. 总之,就是不管做了什么关于library的变动后,最好都ldconfig一下,不然会出现一些意想不到的结果。不会花太多的时间,但是会省很多的事。 +7. 再有,诸如libdb-4.3.so文件头中是会含有库名相关的信息的(即含“libdb-4.3.so”,可用strings命令察看),因此仅通过修改文件名以冒充某已被识别的库(如libdb-4.8.so)是行不通的。为此可在编译库的Makefile中直接修改配置信息,指定特别的库名。 + + + \ No newline at end of file diff --git a/command/ldd.md b/command/ldd.md new file mode 100644 index 0000000000..5705ed02cc --- /dev/null +++ b/command/ldd.md @@ -0,0 +1,48 @@ +ldd +=== + +打印程序或者库文件所依赖的共享库列表 + +## 补充说明 + +**ldd命令** 用于打印程序或者库文件所依赖的共享库列表。 + +### 语法 + +``` +ldd(选项)(参数) +``` + +### 选项 + +``` +--version:打印指令版本号; +-v:详细信息模式,打印所有相关信息; +-u:打印未使用的直接依赖; +-d:执行重定位和报告任何丢失的对象; +-r:执行数据对象和函数的重定位,并且报告任何丢失的对象和函数; +--help:显示帮助信息。 +``` + +### 参数 + +文件:指定可执行程序或者文库。 + +### 其他介绍 + +首先ldd不是一个可执行程序,而只是一个shell脚本 + +ldd能够显示可执行模块的dependency,其原理是通过设置一系列的环境变量,如下:`LD_TRACE_LOADED_OBJECTS、LD_WARN、LD_BIND_NOW、LD_LIBRARY_VERSION、LD_VERBOSE`等。当`LD_TRACE_LOADED_OBJECTS`环境变量不为空时,任何可执行程序在运行时,它都会只显示模块的dependency,而程序并不真正执行。要不你可以在shell终端测试一下,如下: + +``` +export LD_TRACE_LOADED_OBJECTS=1 +``` + +再执行任何的程序,如ls等,看看程序的运行结果。 + +ldd显示可执行模块的dependency的工作原理,其实质是通过ld-linux.so(elf动态库的装载器)来实现的。我们知道,ld-linux.so模块会先于executable模块程序工作,并获得控制权,因此当上述的那些环境变量被设置时,ld-linux.so选择了显示可执行模块的dependency。 + +实际上可以直接执行ld-linux.so模块,如:`/lib/ld-linux.so.2 --list program`(这相当于ldd program) + + + \ No newline at end of file diff --git a/command/losetup.md b/command/losetup.md index 921b0c67fc..75b24af505 100644 --- a/command/losetup.md +++ b/command/losetup.md @@ -10,7 +10,7 @@ losetup ### 语法 ``` -losetup -e encryption +losetup [ -e encryption ] [ -o offset ] loop_device file losetup [ -d ] loop_device ``` diff --git a/command/lpadmin.md b/command/lpadmin.md new file mode 100644 index 0000000000..4f93ea10ba --- /dev/null +++ b/command/lpadmin.md @@ -0,0 +1,38 @@ +lpadmin +=== + +配置CUPS套件中的打印机和类 + +## 补充说明 + +**lpadmin命令** 用于配置CUPS套件中的打印机和类,也被用来设置打印服务器默认打印机。 + +### 语法 + +``` +lpadmin(选项)(参数) +``` + +### 选项 + +``` +-c:将打印机加入类; +-i:为打印机设置“system V”风格的接口脚本; +-m:从mode目录设置一个标准的“system V”接口脚本或“PPD”文件; +-o:为“PPD”或服务器设置选项; +-r:从类中删除打印机; +-u:设置打印机用户级的访问控制; +-D:为打印机提供一个文字描述; +-E:允许打印机接受打印任务; +-L:为打印机位置提供一个文字描述; +-P:为打印机指定一个ppd描述文件; +-p:指定要配置的打印机名称; +-d:设置默认打印机。 +``` + +### 参数 + +打印机:指定要配置的打印机的名称。 + + + \ No newline at end of file diff --git a/command/ls.md b/command/ls.md index a696a2511a..880943d0e9 100644 --- a/command/ls.md +++ b/command/ls.md @@ -205,7 +205,7 @@ drwxr-xr-x 19 root root 4.0K Jun 11 23:38 var 显示文件夹信息 ``` -root@localhost / /etc/ +[root@localhost /]# ls -ld /etc/ drwxr-xr-x 75 root root 4096 Oct 16 04:02 /etc/ diff --git a/command/lynx.md b/command/lynx.md index a621a679b4..535d8c23b7 100644 --- a/command/lynx.md +++ b/command/lynx.md @@ -93,7 +93,7 @@ v:查看一个书签文件。 V:跳转到访问过的地址。 x:不使用缓存。 z:停止当前传输。 -backspace。 +[backspace]:跳转到历史页(同 V 命令)。 =:显示当前页的信息。 :查看当前页的源代码。 !:回到shell提示符下。 diff --git a/command/mail.md b/command/mail.md index 7f95283047..8323adcfa5 100644 --- a/command/mail.md +++ b/command/mail.md @@ -37,17 +37,17 @@ mail(选项)(参数) **直接使用shell当编辑器** ``` -mail -s "Hello from linuxde.net by shell" admin@linuxde.net +mail -s "Hello from jsdig.com by shell" admin@jsdig.com hello,this is the content of mail. -welcome to www.linuxde.net +welcome to www.jsdig.com ``` -第一行是输入的命令,`-s`表示邮件的主题,后面的`admin@linuxde.net`则是邮件的接收人,输入完这行命令后回车,会进入邮件正文的编写,我们可以输入任何文字,比如上面的两行。当邮件正文输入完成后,需要按 **CTRL+D** 结束输入,此时会提示你输入Cc地址,即邮件抄送地址,没有直接回车就完成了邮件的发送。 +第一行是输入的命令,`-s`表示邮件的主题,后面的`admin@jsdig.com`则是邮件的接收人,输入完这行命令后回车,会进入邮件正文的编写,我们可以输入任何文字,比如上面的两行。当邮件正文输入完成后,需要按 **CTRL+D** 结束输入,此时会提示你输入Cc地址,即邮件抄送地址,没有直接回车就完成了邮件的发送。 **使用管道进行邮件发送** ``` -echo "hello,this is the content of mail.welcome to www.linuxde.net" | mail -s "Hello from linuxde.net by pipe" admin@linuxde.net +echo "hello,this is the content of mail.welcome to www.jsdig.com" | mail -s "Hello from jsdig.com by pipe" admin@jsdig.com ``` 使用管道直接敲入这行命令即可完成邮件的发送,其中echo后的是邮件正文。 @@ -55,20 +55,20 @@ echo "hello,this is the content of mail.welcome to www.linuxde.net" | mail -s "H **使用文件进行邮件发送** ``` -mail -s "Hello from linuxde.net by file" admin@linuxde.net < mail.txt +mail -s "Hello from jsdig.com by file" admin@jsdig.com < mail.txt ``` -使用上面的命令后,我们就可以把mail.txt文件的内容作为邮件的内容发送给admin@linuxde.net了。 +使用上面的命令后,我们就可以把mail.txt文件的内容作为邮件的内容发送给admin@jsdig.com了。 使用上述三种方式都可以给外部邮箱进行邮件发送,但因为前面2中都是直接在shell中敲入邮件内容,因此无法输入中文,即使我们使用粘贴的方式输入了中文,那么收到的邮件也是乱码的。但第3种方式,我们可以在window下编辑好邮件内容后,放到linux下,再进行发送,这样就可以正常发送中文了。不过目前邮件的中文标题暂时没有找到解决办法。 因为mail程序本身就是调用sendmail来进行邮件发送的,因此我们可以在mail命令中使用sendmail的参数进行配置,比如我想使用特定的发件人发送邮件,可以使用如下命令: ``` -mail -s "Hello from linuxde.net with sender" admin@linuxde.net -- -f user@linuxde.net \ No newline at end of file diff --git a/command/mkinitrd.md b/command/mkinitrd.md index 984f6a7304..a66f7131ed 100644 --- a/command/mkinitrd.md +++ b/command/mkinitrd.md @@ -34,7 +34,7 @@ mkinitrd(选项)(参数) ### 实例 ``` -root@localhost tmp -r) +[root@localhost tmp]# mkinitrd -v -f myinitrd.img $(uname -r) Creating initramfs WARNING: using /tmp for temporary files Looking for deps of module ide-disk @@ -50,10 +50,10 @@ copy from /lib/modules/2.6.9-5.EL/./kernel/fs/ext3/ext3.ko(elf32-i386) to /tmp/i Loading module jbd Loading module ext3 -root@localhost tmp myinitrd.img +[root@localhost tmp]# file myinitrd.img myinitrd.img: gzip compressed data, from Unix, max compression -root@localhost tmp myinitrd.img myinitrd.img.gz +[root@localhost tmp]# mv myinitrd.img myinitrd.img.gz [root@localhost tmp]# gzip -d myinitrd.img.gz [root@localhost tmp]# file myinitrd.img myinitrd.img: ASCII cpio archive (SVR4 with no CRC) diff --git a/command/netstat.md b/command/netstat.md index e224586252..6fe590c6f5 100644 --- a/command/netstat.md +++ b/command/netstat.md @@ -150,13 +150,13 @@ netstat -i 查看连接某服务端口最多的的IP地址: ``` -netstat -ntu | grep :80 | awk '{print $5}' | cut -d: -f1 | awk '{++ip$1 print ipi -nr +netstat -ntu | grep :80 | awk '{print $5}' | cut -d: -f1 | awk '{++ip[$1]} END {for(i in ip) print ip[i],"\t",i}' | sort -nr ``` TCP各种状态列表: ``` -netstat -nt | grep -e 127.0.0.1 -e 0.0.0.0 -e ::: -v | awk '/^tcp/ {++state$NF print i,"\t",state[i]}' +netstat -nt | grep -e 127.0.0.1 -e 0.0.0.0 -e ::: -v | awk '/^tcp/ {++state[$NF]} END {for(i in state) print i,"\t",state[i]}' ``` 查看phpcgi进程数,如果接近预设值,说明不够用,需要增加: diff --git a/command/ngrep.md b/command/ngrep.md new file mode 100644 index 0000000000..493ed530c2 --- /dev/null +++ b/command/ngrep.md @@ -0,0 +1,139 @@ +ngrep +=== + +方便的数据包匹配和显示工具 + +## 补充说明 + +**ngrep命令** 是grep命令的网络版,他力求更多的grep特征,用于搜寻指定的数据包。正由于安装ngrep需用到libpcap库, 所以支持大量的操作系统和网络协议。能识别TCP、UDP和ICMP包,理解bpf的过滤机制。 + +### 安装 + +ngrep命令的下载地址:http://ngrep.sourceforge.net/,libpcap下载地址:http://www.tcpdump.org/。先用`yum install libpcap`完全安装libpcap,注意有时候用libpcap安装包安装的不完整会影响ngrep的使用。 + +如果yum无法安装就用以下步骤安装libpcap: + +``` +wget http://www.tcpdump.org/release/libpcap-1.3.0.tar.gz +tar -zxf libpcap-1.3.0.tar.gz +cd libpcap-1.3.0 +./configure +make && make install +``` + +ngrep的安装就是 configure/make/make install 三部曲。 + +注:configure时是遇到 please wipe out all unused pcap installations,添加以下选项: + +``` +./configure --with-pcap-includes=/usr/local/include/pcap +``` + +在安装后输入ngrep来验证下安装是否成功。 + +### 语法 + +``` +ngrep <-LhNXViwqpevxlDtTRM> <-IO pcap_dump> <-n num> <-d dev> <-A num> +<-s snaplen> <-S limitlen> <-w normal|byline|single|none> <-c cols> +<-P char> <-F file> +``` + +### 选项 + +``` +-e :显示空数据包 +-i :忽略大小写 +-v :反转匹配 +-R :don't do privilege revocation logic +-x :以16进制格式显示 +-X :以16进制格式匹配 +-w :整字匹配 +-p :不使用混杂模式 +-l :make stdout line buffered +-D :replay pcap_dumps with their recorded time intervals +-t :在每个匹配的包之前显示时间戳 +-T :显示上一个匹配的数据包之间的时间间隔 +-M :仅进行单行匹配 +-I :从文件中读取数据进行匹配 +-O :将匹配的数据保存到文件 +-n :仅捕获指定数目的数据包进行查看 +-A :匹配到数据包后dump随后的指定数目的数据包 +-s :set the bpf caplen +-S :set the limitlen on matched packets +-W :设置显示格式byline将解析包中的换行符 +-c :强制显示列的宽度 +-P :set the non-printable display char to what is specified +-F :使用文件中定义的bpf(Berkeley Packet Filter) +-N :显示由IANA定义的子协议号 +-d :使用哪个网卡,可以用-L选项查询 +-L :查询网卡接口 +``` + +### 实例 + +捕捉cloudian:18080端口的request和response,`-W byline`用来解析包中的换行符,否则包里的所有数据都是连续的,可读性差。`-d lo`是监听本地网卡: + +``` +ngrep -W byline -d lo port 18080 +``` + +捕捉amazon:80端口的request和response。`-d eth0是`用来监听对外的网卡: + +``` +ngrep -W byline -d eth0 port 80 +``` + +可以用`-d any`来捕捉所有的包: + +``` +ngrep '[a-zA-Z]' -t -W byline -d any tcp port 18080 +``` + +捕获字符串`.flv`,比如要查看在Web Flash 视频中的.flv文件的下载地址: + +``` +ngrep -d3 -N -q \.flv +interface: \Device\TNT_40_1_{670F6B50-0A13-4BAB-9D9E-994A833F5BA9} (10.132.0.0/2 +55.255.192.0) +match: \.flv +``` + +打开一个视频页面: + +``` +T(6) 10.132.34.23:24860 -> 61.142.208.154:80 [AP] +GET /f59.c31.56.com/flvdownload/12/19/ggyg7741@56.com_56flv_zhajm_119556973 +97.flv HTTP/1.1..accept: */*..Referer: http://www.56.com/flashApp/v_player_ +site.swf..x-flash-version: 9,0,45,0..UA-CPU: x86..Accept-Encoding: gzip, de +flate..User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET +CLR 2.0.50727; .NET CLR 3.0.04506.30)..host: f59.r.56.com..Connection: Keep +-Alive..Cookie: whistoryview=23423759-23635627-23423344-23171935-23058374-2 +3081156-23207350-22395727-; geoip=............; wl_all_s=y.... +``` + +OK。地址已经找到了,就是http://f59.c31.56.com/flvdownload/12/19/ggyg7741@56.com_56flv_zhajm_11955697397.flv + +加个`-W byline`参数后,将解析包中的换行符: + +``` +T(6) 2007/11/25 15:56:12.192619 10.132.34.23:26365 -> 59.151.21.101:80 [AP] +GET /aa.flv HTTP/1.1. +Accept: */*. +Accept-Language: zh-cn. +UA-CPU: x86. +Accept-Encoding: gzip, deflate. +User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.5072 +7; .NET CLR 3.0.04506.30). +Host: www.google.cn. +Connection: Keep-Alive. +Cookie: PREF=id=a0b2932c336477e9:TB=4:NW=1:TM=1187877372:LM=1187956074:S=Y1Fzndp +rT3vFo7ac; SID=DQAAAHcAAABJCEXeOVLHu2rIfb5BfKP3GG9PbhJDEkXsLTV8y0f_lvSd2Y46Q0FPt +83CnEs9rxA1xBDM9mLR8-ckWeScyOQA8PyYnX5u5OjFvjfRbDg_FDZfwxhRzqS9KPZv26pjnsUxs0FDM +1xpJ5AgDn38pXtlCdkksJ0-cbiIWoA61oHWMg; NID=7=AvJxn5B6YOLLxoYz4LLzhIbNsQUQiulRS6U +JGxdBniQBmXm99y7L-NBNORN82N3unmZSGHFPfePVHnLK2MjYjglyXZhU9x7ETXNBnY3NurNijHDhJ7K +yi7E53UBOcv4V. +``` + + + \ No newline at end of file diff --git a/command/nm.md b/command/nm.md new file mode 100644 index 0000000000..519138a9a2 --- /dev/null +++ b/command/nm.md @@ -0,0 +1,30 @@ +nm +=== + +显示二进制目标文件的符号表 + +## 补充说明 + +**nm命令** 被用于显示二进制目标文件的符号表。 + +### 语法 + +``` +nm(选项)(参数) +``` + +### 选项 + +``` +-A:每个符号前显示文件名; +-D:显示动态符号; +-g:仅显示外部符号; +-r:反序显示符号表。 +``` + +### 参数 + +目标文件:二进制目标文件,通常是库文件和可执行文件。 + + + \ No newline at end of file diff --git a/command/nslookup.md b/command/nslookup.md index 51f4984f69..7e5e9114ca 100644 --- a/command/nslookup.md +++ b/command/nslookup.md @@ -30,13 +30,13 @@ nslookup(选项)(参数) ### 实例 ``` -[root@localhost ~]# nslookup www.linuxde.net +[root@localhost ~]# nslookup www.jsdig.com Server: 202.96.104.15 Address: 202.96.104.15#53 Non-authoritative answer: -www.linuxde.net canonical name = host.1.linuxde.net. -Name: host.1.linuxde.net +www.jsdig.com canonical name = host.1.jsdig.com. +Name: host.1.jsdig.com Address: 100.42.212.8 ``` diff --git a/command/ntpdate.md b/command/ntpdate.md new file mode 100644 index 0000000000..aeffc69e0e --- /dev/null +++ b/command/ntpdate.md @@ -0,0 +1,118 @@ +ntpdate +=== + +使用网络计时协议(NTP)设置日期和时间 + +## 补充说明 + +**ntpdate命令** 是用来设置本地日期和时间。它从指定的每个服务器获得了一些样本,并应用标准 NTP 时钟过滤器和选择算法来选择最好的样本。 + +此 ntpdate 命令使用以下方法进行时间调整: + +* 如果它确定时钟偏差超过 0.5 秒,它通过调用 settimeofday 子例程设置时钟时间。在引导时间,这是一个首选的方法。 +* 如 果它确定时钟偏差小于 0.5 秒,它通过调用 adjtime 子例程和偏移量来调整时钟时间。此方法倾向于用牺牲一些稳定性来保持漂移时钟更加准确。 当不是通过运行一个守护程序而是从 cron 命令有规则的运行ntpdate 命令时,每一小时或两小时执行一次可以保证足够的走时精度,从而避免调整时钟。 + +使用很多服务器可以大幅度改善 ntpdate 命令的可靠性与精度。尽管能使用单一服务器,但您能通过提供至少三个或四个服务器以获得更好的性能。 + +如果一个类似 xntpd 守护程序的 NTP 服务器守护程序正在同一主机上运行,命令将拒绝ntpdate 设置日期。 + +你必须有 root 权限才能在主机上运行这个命令。 + +### 语法 + +``` +ntpdate [ -b] [ -d] [ -s] [ -u] [ -aKeyid] [ -eAuthenticationDelay] [ -kKeyFile] [ -oVersion] [ -pSamples] [ -tTimeOut] Server... +``` + +### 选项 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-aKeyid使用 Keyid 来认证全部数据包。
-b通过调用 settimeofday 子例程来增加时钟的时间。
-d指定调试方式。判断 ntpdate 命令会产生什么结果(不产生实际的结果)。结果再现在屏幕上。这个标志使用无特权的端口。
-eAuthenticationDelay指定延迟认证处理的时间秒数。
-kKeyFile当不使用缺省值 /etc/ntp.keys 文件时,为包含密钥的文件指定一个不同的名称。 请参阅文件KeyFile的描述。
-oVersion当轮询它的发出数据包时,指定使用的 NTP 版本实现。 Version 的值可以是 1,2,3。缺省值是 3。
-pSamples指定从每个服务器获取的样本的数目。 Samples 的值在 1 和 8 之间,并包括 1 和 8。它的缺省值是 4。
-s指定日志操作 syslog 设施的使用,而不是使用标准输出。 当运行 ntpdate 命令和 cron命令时,它是很有用的。
-tTimeOut指定等待响应的时间。给定 TimeOut 的值四舍五入为 0.2 秒的倍数。缺省值是 1 秒。
-u指定使用无特权的端口发送数据包。 当在一个对特权端口的输入流量进行阻拦的防火墙后是很有益的, 并希望在防火墙之外和主机同步。防火墙是一个系统或者计算机,它控制从外网对专用网的访问。
+ + + \ No newline at end of file diff --git a/command/objdump.md b/command/objdump.md new file mode 100644 index 0000000000..3fd1fd9443 --- /dev/null +++ b/command/objdump.md @@ -0,0 +1,494 @@ +objdump +=== + +显示二进制文件信息 + +## 补充说明 + +**objdump命令** 是用查看目标文件或者可执行的目标文件的构成的gcc工具。 + +### 选项 + +``` +--archive-headers +-a +显示档案库的成员信息,类似ls -l将lib*.a的信息列出。 + +-b bfdname +--target=bfdname +指定目标码格式。这不是必须的,objdump能自动识别许多格式,比如: + +objdump -b oasys -m vax -h fu.o +显示fu.o的头部摘要信息,明确指出该文件是Vax系统下用Oasys编译器生成的目标文件。objdump -i将给出这里可以指定的目标码格式列表。 + +-C +--demangle +将底层的符号名解码成用户级名字,除了去掉所开头的下划线之外,还使得C++函数名以可理解的方式显示出来。 + +--debugging +-g +显示调试信息。企图解析保存在文件中的调试信息并以C语言的语法显示出来。仅仅支持某些类型的调试信息。有些其他的格式被readelf -w支持。 + +-e +--debugging-tags +类似-g选项,但是生成的信息是和ctags工具相兼容的格式。 + +--disassemble +-d +从objfile中反汇编那些特定指令机器码的section。 + +-D +--disassemble-all +与 -d 类似,但反汇编所有section. + +--prefix-addresses +反汇编的时候,显示每一行的完整地址。这是一种比较老的反汇编格式。 + +-EB +-EL +--endian={big|little} +指定目标文件的小端。这个项将影响反汇编出来的指令。在反汇编的文件没描述小端信息的时候用。例如S-records. + +-f +--file-headers +显示objfile中每个文件的整体头部摘要信息。 + +-h +--section-headers +--headers +显示目标文件各个section的头部摘要信息。 + +-H +--help +简短的帮助信息。 + +-i +--info +显示对于 -b 或者 -m 选项可用的架构和目标格式列表。 + +-j name +--section=name +仅仅显示指定名称为name的section的信息 + +-l +--line-numbers +用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。 + +-m machine +--architecture=machine +指定反汇编目标文件时使用的架构,当待反汇编文件本身没描述架构信息的时候(比如S-records),这个选项很有用。可以用-i选项列出这里能够指定的架构. + +--reloc +-r +显示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反汇编后的格式显示出来。 + +--dynamic-reloc +-R +显示文件的动态重定位入口,仅仅对于动态目标文件意义,比如某些共享库。 + +-s +--full-contents +显示指定section的完整内容。默认所有的非空section都会被显示。 + +-S +--source +尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。隐含了-d参数。 + +--show-raw-insn +反汇编的时候,显示每条汇编指令对应的机器码,如不指定--prefix-addresses,这将是缺省选项。 + +--no-show-raw-insn +反汇编时,不显示汇编指令的机器码,如不指定--prefix-addresses,这将是缺省选项。 + +--start-address=address +从指定地址开始显示数据,该选项影响-d、-r和-s选项的输出。 + +--stop-address=address +显示数据直到指定地址为止,该项影响-d、-r和-s选项的输出。 + +-t +--syms +显示文件的符号表入口。类似于nm -s提供的信息 + +-T +--dynamic-syms +显示文件的动态符号表入口,仅仅对动态目标文件意义,比如某些共享库。它显示的信息类似于 nm -D|--dynamic 显示的信息。 + +-V +--version +版本信息 + +--all-headers +-x +显示所可用的头信息,包括符号表、重定位入口。-x 等价于-a -f -h -r -t 同时指定。 + +-z +--disassemble-zeroes +一般反汇编输出将省略大块的零,该选项使得这些零块也被反汇编。 + +@file 可以将选项集中到一个文件中,然后使用这个@file选项载入。 +``` + +### 实例 + +首先,在给出后面大部分测试所基于的源代码以及编译指令。 源代码如下:  + +``` +root@localhost [test]# nl mytest.cpp +``` + +``` +void printTest() { + char a; + a = 'a'; +} + +void printTest2() { +int a = 2; +a+=2; +} +``` + +对以上源代码进行编译,如下:  + +``` +[root@localhost test]# g++ -c -g mytest.cpp +``` + +这里,生成的文件是mytest.o,为了方便测试包含了调试的信息,对可执行文件的测试,显示的结果类似。  + + **查看当前使用的objdump的版本号: ** + +``` +[root@localhost test]# objdump -V +GNU objdump 2.17.50.0.6-14.el5 20061020 +Copyright 2005 free Software Foundation, Inc. +This program is free software; you may redistribute it under the terms of +the GNU General Public License. This program has absolutely no warranty. +``` + + **查看档案库文件中的信息: ** + +``` +[root@localhost test]# objdump -a libmy2.a +In archive libmy2.a: +myfile.o: file format elf32-i386 +rwxrwxrwx 0/0 2724 Nov 16 16:06 2009 myfile.o +mytest.o: file format elf32-i386 +rw-r--r-- 0/0 727 Jul 13 15:32 2011 mytest.o +``` + + **这里,libmy2.a是一个使用ar命令将多个*.o目标文件打包而生成的静态库。命令的输出类似`ar -tv`,相比较`ar -tv`输出如下: ** + +``` +[root@localhost test]# ar -tv libmy2.a +rwxrwxrwx 0/0 2724 Nov 16 16:06 2009 myfile.o +rw-r--r-- 0/0 727 Jul 13 15:32 2011 mytest.o +``` + +显示可用的架构和目标结构列表:  + +``` +[root@localhost test]# objdump -i +BFD header file version 2.17.50.0.6-14.el5 20061020 +elf32-i386 +(header little endian, data little endian) + i386 +a.out-i386-linux +(header little endian, data little endian) + i386 +efi-app-ia32 +(header little endian, data little endian) + i386 +elf64-x86-64 +(header little endian, data little endian) + i386 +elf64-little +(header little endian, data little endian) + i386 +elf64-big +(header big endian, data big endian) + i386 +elf32-little +(header little endian, data little endian) + i386 +elf32-big +(header big endian, data big endian) + i386 +srec +(header endianness unknown, data endianness unknown) + i386 +symbolsrec +(header endianness unknown, data endianness unknown) + i386 +tekhex +(header endianness unknown, data endianness unknown) + i386 +binary +(header endianness unknown, data endianness unknown) + i386 +ihex +(header endianness unknown, data endianness unknown) + i386 +trad-core +(header endianness unknown, data endianness unknown) + + elf32-i386 a.out-i386-linux efi-app-ia32 elf64-x86-64 + i386 elf32-i386 a.out-i386-linux efi-app-ia32 elf64-x86-64 + + elf64-little elf64-big elf32-little elf32-big srec symbolsrec + i386 elf64-little elf64-big elf32-little elf32-big srec symbolsrec + + tekhex binary ihex trad-core + i386 tekhex binary ihex --------- +``` + +这里,显示的信息是相对于 -b 或者 -m 选项可用的架构和目标格式列表。  + + **显示mytest.o文件中的text段的内容: ** + +``` +[root@localhost test]# objdump --section=.text -s mytest.o +mytest.o: file format elf32-i386 +Contents of section .text: +0000 5589e583 ec10c645 ff61c9c3 5589e583 U......E.a..U... +0010 ec10c745 fc020000 008345fc 02c9c3 ...E......E.... +``` + +这里注意,不能单独使用-j或者--section,例如`objdump --section=.text mytest.o`是不会运行成功的。  + + **反汇编mytest.o中的text段内容,并尽可能用源代码形式表示: ** + +``` +[root@localhost test]# objdump -j .text -S mytest.o +mytest.o: file format elf32-i386 +Disassembly of section .text: +00000000 <_Z9printTestv>: +void printTest() + 0: 55 push %ebp + 1: 89 e5 mov %esp,%ebp + 3: 83 ec 10 sub $0x10,%esp +{ + char a; + a = 'a'; + 6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp) +} + a: c9 leave + b: c3 ret + +000000c <_Z10printTest2v>: +void printTest2() + c: 55 push %ebp + d: 89 e5 mov %esp,%ebp + f: 83 ec 10 sub $0x10,%esp +{ + int a = 2; + 12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp) + a+=2; + 19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp) +} + 1d: c9 leave + 1e: c3 ret +``` + +这里注意,不能单独使用-j或者--section,例如`objdump -j .text mytest.o是不会运行成功的`。另外-S命令对于包含调试信息的目标文件,显示的效果比较好,如果编译时没有指定g++的-g选项,那么目标文件就不包含调试信息,那么显示效果就差多了。  + + **反汇编出mytest.o的源代码: ** + +``` +[root@localhost test]# objdump -S mytest.o +mytest.o: file format elf32-i386 + +Disassembly of section .text: + +00000000 <_Z9printTestv>: +void printTest() + 0: 55 push %ebp + 1: 89 e5 mov %esp,%ebp + 3: 83 ec 10 sub $0x10,%esp +{ + char a; + a = 'a'; + 6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp) +} + a: c9 leave + b: c3 ret + +0000000c <_Z10printTest2v>: +void printTest2() + c: 55 push %ebp + d: 89 e5 mov %esp,%ebp + f: 83 ec 10 sub $0x10,%esp +{ + int a = 2; + 12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp) + a+=2; + 19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp) +} + 1d: c9 leave + 1e: c3 ret +``` + +这里,尤其当编译的时候指定了-g这种调试参数时,反汇编的效果比较明显。隐含了-d参数。  + + **显示文件的符号表入口: ** + +``` +[root@localhost test]# objdump -t mytest.o +mytest.o: file format elf32-i386 + +SYMBOL TABLE: +00000000 l df *ABS* 00000000 mytest.cpp +00000000 l d .text 00000000 .text +00000000 l d .data 00000000 .data +00000000 l d .bss 00000000 .bss +00000000 l d .debug_abbrev 00000000 .debug_abbrev +00000000 l d .debug_info 00000000 .debug_info +00000000 l d .debug_line 00000000 .debug_line +00000000 l d .debug_frame 00000000 .debug_frame +00000000 l d .debug_loc 00000000 .debug_loc +00000000 l d .debug_pubnames 00000000 .debug_pubnames +00000000 l d .debug_aranges 00000000 .debug_aranges +00000000 l d .note.GNU-stack 00000000 .note.GNU-stack +00000000 l d .comment 00000000 .comment +00000000 g F .text 0000000c _Z9printTestv +00000000 *UND* 00000000 __gxx_personality_v0 +0000000c g F .text 00000013 _Z10printTest2v +``` + +这里,输出的信息类似`nm -s`命令的输出,相比较之下,nm命令的输出如下:  + +``` +[root@localhost test]# nm -s mytest.o +0000000c T _Z10printTest2v +00000000 T _Z9printTestv + U __gxx_personality_v0 +``` + + **显示文件的符号表入口,将底层符号解码并表示成用户级别: ** + +``` +[root@localhost test]# objdump -t -C mytest.o +mytest.o: file format elf32-i386 +SYMBOL TABLE: +00000000 l df *ABS* 00000000 mytest.cpp +00000000 l d .text 00000000 .text +00000000 l d .data 00000000 .data +00000000 l d .bss 00000000 .bss +00000000 l d .debug_abbrev 00000000 .debug_abbrev +00000000 l d .debug_info 00000000 .debug_info +00000000 l d .debug_line 00000000 .debug_line +00000000 l d .debug_frame 00000000 .debug_frame +00000000 l d .debug_loc 00000000 .debug_loc +00000000 l d .debug_pubnames 00000000 .debug_pubnames +00000000 l d .debug_aranges 00000000 .debug_aranges +00000000 l d .note.GNU-stack 00000000 .note.GNU-stack +00000000 l d .comment 00000000 .comment +00000000 g F .text 0000000c printTest() +00000000 *UND* 00000000 __gxx_personality_v0 +0000000c g F .text 00000013 printTest2() +``` + +这里,和没-C相比,printTest2函数可读性增加了。  + + **反汇编目标文件的特定机器码段: ** + +``` +[root@localhost test]# objdump -d mytest.o +mytest.o: file format elf32-i386 +Disassembly of section .text: + +00000000 <_Z9printTestv>: + 0: 55 push %ebp + 1: 89 e5 mov %esp,%ebp + 3: 83 ec 10 sub $0x10,%esp + 6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp) + a: c9 leave + b: c3 ret + +0000000c <_Z10printTest2v>: + c: 55 push %ebp + d: 89 e5 mov %esp,%ebp + f: 83 ec 10 sub $0x10,%esp + 12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp) + 19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp) + 1d: c9 leave + 1e: c3 ret +``` + +这里,对text段的内容进行了反汇编。  + + **反汇编特定段,并将汇编代码对应的文件名称和行号对应上: ** + +``` +[root@localhost test]# objdump -d -l mytest.o +mytest.o: file format elf32-i386 +Disassembly of section .text: + +00000000 <_Z9printTestv>: +_Z9printTestv(): +/root/test/04_libraryTest/mytest.cpp:1 + 0: 55 push %ebp + 1: 89 e5 mov %esp,%ebp + 3: 83 ec 10 sub $0x10,%esp +/root/test/04_libraryTest/mytest.cpp:4 + 6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp) +/root/test/04_libraryTest/mytest.cpp:5 + a: c9 leave + b: c3 ret + +0000000c <_Z10printTest2v>: +_Z10printTest2v(): +/root/test/04_libraryTest/mytest.cpp:6 + c: 55 push %ebp + d: 89 e5 mov %esp,%ebp + f: 83 ec 10 sub $0x10,%esp +/root/test/04_libraryTest/mytest.cpp:8 + 12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp) +/root/test/04_libraryTest/mytest.cpp:9 + 19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp) +/root/test/04_libraryTest/mytest.cpp:10 + 1d: c9 leave + 1e: c3 ret +``` + +这里,项"-d"从objfile中反汇编那些特定指令机器码的section,而使用"-l"指定用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用,使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。  + + **显示目标文件各个段的头部摘要信息: ** + +``` +[root@localhost test]# objdump -h mytest.o +mytest.o: file format elf32-i386 + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .text 0000001f 00000000 00000000 00000034 2**2 + CONTENTS, ALLOC, LOAD, readonly, CODE + 1 .data 00000000 00000000 00000000 00000054 2**2 + CONTENTS, ALLOC, LOAD, DATA + 2 .bss 00000000 00000000 00000000 00000054 2**2 + ALLOC + 3 .debug_abbrev 00000046 00000000 00000000 00000054 2**0 + CONTENTS, READONLY, DEBUGGING + 4 .debug_info 000000ed 00000000 00000000 0000009a 2**0 + CONTENTS, RELOC, READONLY, DEBUGGING + 5 .debug_line 0000003e 00000000 00000000 00000187 2**0 + CONTENTS, RELOC, READONLY, DEBUGGING + 6 .debug_frame 00000044 00000000 00000000 000001c8 2**2 + CONTENTS, RELOC, READONLY, DEBUGGING + 7 .debug_loc 00000058 00000000 00000000 0000020c 2**0 + CONTENTS, READONLY, DEBUGGING + 8 .debug_pubnames 0000002f 00000000 00000000 00000264 2**0 + CONTENTS, RELOC, READONLY, DEBUGGING + 9 .debug_aranges 00000020 00000000 00000000 00000293 2**0 + CONTENTS, RELOC, READONLY, DEBUGGING +10 .comment 0000002e 00000000 00000000 000002b3 2**0 + CONTENTS, READONLY +11 .note.GNU-stack 00000000 00000000 00000000 000002e1 2**0 + CONTENTS, READONLY +``` + +这里,更多的内容参见`man objdump`中的这个选项。 + + + \ No newline at end of file diff --git a/command/od.md b/command/od.md index c5950d4163..0e403cd351 100644 --- a/command/od.md +++ b/command/od.md @@ -46,8 +46,8 @@ od(选项)(参数) ### 实例 ``` -linuxde@localhost ~ abcdef g > tmp -linuxde@localhost ~ tmp +[linuxde@localhost ~]$ echo abcdef g > tmp +[linuxde@localhost ~]$ cat tmp abcdef g ``` diff --git a/command/passwd.md b/command/passwd.md index 6b4833827a..26a603a95a 100644 --- a/command/passwd.md +++ b/command/passwd.md @@ -103,7 +103,7 @@ passwd: all authentication tokens updated successfully. //更改成功; Locking password for user linuxde. passwd: Success //锁定成功; -linuxde@localhost ~ linuxde //通过su切换到linuxde用户; +[linuxde@localhost ~]# su linuxde //通过su切换到linuxde用户; [linuxde@localhost ~]$ passwd //linuxde来更改密码; Changing password for user linuxde. Changing password for linuxde diff --git a/command/perl.md b/command/perl.md new file mode 100644 index 0000000000..5e26f1ec20 --- /dev/null +++ b/command/perl.md @@ -0,0 +1,30 @@ +perl +=== + +perl语言解释器 + +## 补充说明 + +**perl命令** 是perl语言解释器,负责解释执行perl语言程序。 + +### 语法 + +``` +perl(选项)(参数) +``` + +### 选项 + +``` +-w:输出有用的警告信息; +-U:允许不安全的操作; +-c:仅检查文件的语法; +-d:在调试下运行脚本程序。 +``` + +### 参数 + +文件:要运行的perl脚本程序。 + + + \ No newline at end of file diff --git a/command/pgrep.md b/command/pgrep.md index 641dcbaa85..3539746bb2 100644 --- a/command/pgrep.md +++ b/command/pgrep.md @@ -34,7 +34,7 @@ pgrep(选项)(参数) ``` pgrep -lo httpd 4557 httpd - root@localhost ~ httpd + [root@localhost ~]# pgrep -ln httpd 4566 httpd [root@localhost ~]# pgrep -l httpd diff --git a/command/php.md b/command/php.md new file mode 100644 index 0000000000..75ba12d552 --- /dev/null +++ b/command/php.md @@ -0,0 +1,28 @@ +php +=== + +PHP语言的命令行接口 + +## 补充说明 + +**php命令** 是流行的Web开发语言PHP的命令行接口,可以使用PHP语言开发基于命令行的系统管理脚本程序。 + +### 语法 + +``` +php(选项)(参数) +``` + +### 选项 + +``` +-a:进入交互模式; +-c:指定“php.ini”的搜索路径。 +``` + +### 参数 + +文件:要执行的php脚本。 + + + \ No newline at end of file diff --git a/command/ping.md b/command/ping.md index 597a22a069..8e6abf6f9d 100644 --- a/command/ping.md +++ b/command/ping.md @@ -39,15 +39,15 @@ ping(选项)(参数) ### 实例 ``` -[root@AY1307311912260196fcZ ~]# ping www.linuxde.net -PING host.1.linuxde.net (100.42.212.8) 56(84) bytes of data. +[root@AY1307311912260196fcZ ~]# ping www.jsdig.com +PING host.1.jsdig.com (100.42.212.8) 56(84) bytes of data. 64 bytes from 100-42-212-8.static.webnx.com (100.42.212.8): icmp_seq=1 ttl=50 time=177 ms 64 bytes from 100-42-212-8.static.webnx.com (100.42.212.8): icmp_seq=2 ttl=50 time=178 ms 64 bytes from 100-42-212-8.static.webnx.com (100.42.212.8): icmp_seq=3 ttl=50 time=174 ms 64 bytes from 100-42-212-8.static.webnx.com (100.42.212.8): icmp_seq=4 ttl=50 time=177 ms ...按Ctrl+C结束 ---- host.1.linuxde.net ping statistics --- +--- host.1.jsdig.com ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 2998ms rtt min/avg/max/mdev = 174.068/176.916/178.182/1.683 ms ``` diff --git a/command/protoize.md b/command/protoize.md new file mode 100644 index 0000000000..48c28afa4b --- /dev/null +++ b/command/protoize.md @@ -0,0 +1,28 @@ +protoize +=== + +GNU-C代码转换为ANSI-C代码 + +## 补充说明 + +**protoize命令** 属于gcc套件,用于为C语言源代码文件添加函数原型,将GNU-C代码转换为ANSI-C代码。 + +### 语法 + +``` +protoize(选项)(参数) +``` + +### 选项 + +``` +-d:设置需要转换代码的目录; +-x:转换代码时排除的文件。 +``` + +### 参数 + +文件:需要转换代码的C语言源文件。 + + + \ No newline at end of file diff --git a/command/pssh.md b/command/pssh.md new file mode 100644 index 0000000000..fe15908f7a --- /dev/null +++ b/command/pssh.md @@ -0,0 +1,106 @@ +pssh +=== + +批量管理执行 + +## 补充说明 + +**pssh命令** 是一个python编写可以在多台服务器上执行命令的工具,同时支持拷贝文件,是同类工具中很出色的,类似pdsh,个人认为相对pdsh更为简便,使用必须在各个服务器上配置好密钥认证访问。 + +### 安装pssh + +在CentOS系统环境下,介绍yum的安装和源码安装的方式: + + **yum方法** + +``` +yum install pssh +``` + + **编译安装** + +``` +wget http://parallel-ssh.googlecode.com/files/pssh-2.3.1.tar.gz +tar xf pssh-2.3.1.tar.gz +cd pssh-2.3.1/ +python setup.py install +``` + +### 选项 + +``` +--version:查看版本 +--help:查看帮助,即此信息 +-h:主机文件列表,内容格式”[user@]host[:port]” +-H:主机字符串,内容格式”[user@]host[:port]” +-:登录使用的用户名 +-p:并发的线程数【可选】 +-o:输出的文件目录【可选】 +-e:错误输入文件【可选】 +-t:TIMEOUT 超时时间设置,0无限制【可选】 +-O:SSH的选项 +-v:详细模式 +-A:手动输入密码模式 +-x:额外的命令行参数使用空白符号,引号,反斜线处理 +-X:额外的命令行参数,单个参数模式,同-x +-i:每个服务器内部处理信息输出 +-P:打印出服务器返回信息 +``` + +### 实例 + +获取每台服务器的uptime: + +``` +# pssh -h ip.txt -i uptime +[1] 11:15:03 [SUCCESS] Mar.mars.he +11:15:11 up 4 days, 16:25, 1 user, load average: 0.00, 0.00, 0.00 +[2] 11:15:03 [SUCCESS] Jan.mars.he +11:15:12 up 3 days, 23:26, 0 users, load average: 0.00, 0.00, 0.00 +[3] 11:15:03 [SUCCESS] Feb.mars.he +11:15:12 up 4 days, 16:26, 2 users, load average: 0.08, 0.02, 0.01 +``` + +查看每台服务器上mysql复制IO/SQL线程运行状态信息: + +``` +# pssh -h IP.txt -i "/usr/local/mysql/bin/mysql -e 'show slave status \G'"|grep Running: + Slave_IO_Running: yes + Slave_SQL_Running: Yes + Slave_IO_Running: Yes + Slave_SQL_Running: Yes + Slave_IO_Running: Yes + Slave_SQL_Running: Yes +``` + +保存每台服务器运行的结果: + +``` +# pssh -h IP.txt -i -o /tmp/pssh/ uptime +[1] 11:19:47 [SUCCESS] Feb.mars.he +11:19:55 up 4 days, 16:31, 2 users, load average: 0.02, 0.03, 0.00 +[2] 11:19:47 [SUCCESS] Jan.mars.he +11:19:56 up 3 days, 23:30, 0 users, load average: 0.01, 0.00, 0.00 +[3] 11:19:47 [SUCCESS] Mar.mars.he +11:19:56 up 4 days, 16:30, 1 user, load average: 0.00, 0.00, 0.00 +``` + +我们来看一下/tmp/pssh/下的文件及其内容 + +``` +# ll /tmp/pssh/ +总用量 12 +-rw-r--r--. 1 root root 70 12月 1 11:19 Feb.mars.he +-rw-r--r--. 1 root root 70 12月 1 11:19 Jan.mars.he +-rw-r--r--. 1 root root 69 12月 1 11:19 Mar.mars.he + +# cat /tmp/pssh/* +11:19:55 up 4 days, 16:31, 2 users, load average: 0.02, 0.03, 0.00 +11:19:56 up 3 days, 23:30, 0 users, load average: 0.01, 0.00, 0.00 +11:19:56 up 4 days, 16:30, 1 user, load average: 0.00, 0.00, 0.00 +``` + +上面介绍的是pssh命令很少的一部分,大家可以将其用到适合自己的场景,发挥它的最大功效。 + + + \ No newline at end of file diff --git a/command/pstack.md b/command/pstack.md new file mode 100644 index 0000000000..e2ea0f2a0c --- /dev/null +++ b/command/pstack.md @@ -0,0 +1,101 @@ +pstack +=== + +显示每个进程的栈跟踪 + +## 补充说明 + +**pstack命令** 可显示每个进程的栈跟踪。pstack 命令必须由相应进程的属主或 root 运行。可以使用 pstack 来确定进程挂起的位置。此命令允许使用的唯一选项是要检查的进程的 PID。 + +命令软件包下载地址:https://packages.debian.org/sid/pstack + +### 实例 + +pstree以树结构显示进程 + +``` +pstree -p work | grep ad +sshd(22669)---bash(22670)---ad_preprocess(4551)-+-{ad_preprocess}(4552) + |-{ad_preprocess}(4553) + |-{ad_preprocess}(4554) + |-{ad_preprocess}(4555) + |-{ad_preprocess}(4556) + `-{ad_preprocess}(4557) +``` + +work为工作用户,-p为显示进程识别码,ad_preprocess共启动了6个子线程,加上主线程共7个线程。 + +``` +ps -Lf 4551 +UID PID PPID LWP C NLWP STIME TTY stat time CMD +work 4551 22670 4551 2 7 16:30 pts/2 Sl+ 0:02 ./ad_preprocess +work 4551 22670 4552 0 7 16:30 pts/2 Sl+ 0:00 ./ad_preprocess +work 4551 22670 4553 0 7 16:30 pts/2 Sl+ 0:00 ./ad_preprocess +work 4551 22670 4554 0 7 16:30 pts/2 Sl+ 0:00 ./ad_preprocess +work 4551 22670 4555 0 7 16:30 pts/2 Sl+ 0:00 ./ad_preprocess +work 4551 22670 4556 0 7 16:30 pts/2 Sl+ 0:00 ./ad_preprocess +work 4551 22670 4557 0 7 16:30 pts/2 Sl+ 0:00 ./ad_preprocess +``` + +进程共启动了7个线程 + +pstack显示每个进程的栈跟踪: + +``` +pstack 4551 +Thread 7 (Thread 1084229984 (LWP 4552)): +#0 0x000000302afc63dc in epoll_wait () from /lib64/tls/libc.so.6 +#1 0x00000000006f0730 in ub::EPollEx::poll () +#2 0x00000000006f172a in ub::NetReactor::callback () +#3 0x00000000006fbbbb in ub::UBTask::CALLBACK () +#4 0x000000302b80610a in start_thread () from /lib64/tls/libpthread.so.0 +#5 0x000000302afc6003 in clone () from /lib64/tls/libc.so.6 +#6 0x0000000000000000 in ?? () +Thread 6 (Thread 1094719840 (LWP 4553)): +#0 0x000000302afc63dc in epoll_wait () from /lib64/tls/libc.so.6 +#1 0x00000000006f0730 in ub::EPollEx::poll () +#2 0x00000000006f172a in ub::NetReactor::callback () +#3 0x00000000006fbbbb in ub::UBTask::CALLBACK () +#4 0x000000302b80610a in start_thread () from /lib64/tls/libpthread.so.0 +#5 0x000000302afc6003 in clone () from /lib64/tls/libc.so.6 +#6 0x0000000000000000 in ?? () +Thread 5 (Thread 1105209696 (LWP 4554)): +#0 0x000000302b80baa5 in __nanosleep_nocancel () +#1 0x000000000079e758 in comcm::ms_sleep () +#2 0x00000000006c8581 in ub::UbClientManager::healthyCheck () +#3 0x00000000006c8471 in ub::UbClientManager::start_healthy_check () +#4 0x000000302b80610a in start_thread () from /lib64/tls/libpthread.so.0 +#5 0x000000302afc6003 in clone () from /lib64/tls/libc.so.6 +#6 0x0000000000000000 in ?? () +Thread 4 (Thread 1115699552 (LWP 4555)): +#0 0x000000302b80baa5 in __nanosleep_nocancel () +#1 0x0000000000482b0e in armor::armor_check_thread () +#2 0x000000302b80610a in start_thread () from /lib64/tls/libpthread.so.0 +#3 0x000000302afc6003 in clone () from /lib64/tls/libc.so.6 +#4 0x0000000000000000 in ?? () +Thread 3 (Thread 1126189408 (LWP 4556)): +#0 0x000000302af8f1a5 in __nanosleep_nocancel () from /lib64/tls/libc.so.6 +#1 0x000000302af8f010 in sleep () from /lib64/tls/libc.so.6 +#2 0x000000000044c972 in Business_config_manager::run () +#3 0x0000000000457b83 in Thread::run_thread () +#4 0x000000302b80610a in start_thread () from /lib64/tls/libpthread.so.0 +#5 0x000000302afc6003 in clone () from /lib64/tls/libc.so.6 +#6 0x0000000000000000 in ?? () +Thread 2 (Thread 1136679264 (LWP 4557)): +#0 0x000000302af8f1a5 in __nanosleep_nocancel () from /lib64/tls/libc.so.6 +#1 0x000000302af8f010 in sleep () from /lib64/tls/libc.so.6 +#2 0x00000000004524bb in Process_thread::sleep_period () +#3 0x0000000000452641 in Process_thread::run () +#4 0x0000000000457b83 in Thread::run_thread () +#5 0x000000302b80610a in start_thread () from /lib64/tls/libpthread.so.0 +#6 0x000000302afc6003 in clone () from /lib64/tls/libc.so.6 +#7 0x0000000000000000 in ?? () +Thread 1 (Thread 182894129792 (LWP 4551)): +#0 0x000000302af8f1a5 in __nanosleep_nocancel () from /lib64/tls/libc.so.6 +#1 0x000000302af8f010 in sleep () from /lib64/tls/libc.so.6 +#2 0x0000000000420d79 in Ad_preprocess::run () +#3 0x0000000000450ad0 in main () +``` + + + \ No newline at end of file diff --git a/command/quota.md b/command/quota.md index 269100ab7f..24a79fed5c 100644 --- a/command/quota.md +++ b/command/quota.md @@ -34,18 +34,18 @@ quota(选项)(参数) 要求:Linux 主机里面主要针对 quser1 及 quser2 两个使用者来进行磁盘配额, 且这两个使用者都是挂在 qgroup 组里面的。每个使用者总共有 50MB 的磁盘空间 (不考虑 inode) 限制!并且 soft limit 为 45 MB;而宽限时间设定为 1 天, 但是在一天之内必须要将多余的文件删除掉,否则将无法使用剩下的空间 ;gquota 这个组考虑最大限额,所以设定为 90 MB!(注意,这样设置的好处是富有弹性,好比现在的邮件服务,那么多用户,承诺给用户每人最大空间为数GB,然而人们不可能每人都会使用那么大的空间,所以邮件服务的总空间,实际上肯定不是注册客户数乘以数GB,否则这样得多大啊。) ``` -root@localhost ~ qgroup -root@localhost ~ -m -g qgroup quser1 +[root@localhost ~]# groupadd qgroup +[root@localhost ~]# useradd -m -g qgroup quser1 [root@localhost ~]# useradd -m -g qgroup quser2 -root@localhost ~ quser1 +[root@localhost ~]# passwd quser1 [root@localhost ~]# passwd quser2 -root@localhost ~ ===> 自己找一个合适的分区来做实验,这里用/disk2 +[root@localhost ~]# df ===> 自己找一个合适的分区来做实验,这里用/disk2 Filesystem 1K-blocks Used Available Use% Mounted on /dev/hda1 5952252 3193292 2451720 57% / /dev/hdb1 28267608 77904 26730604 1% /disk2 /dev/hda5 9492644 227252 8775412 3% /disk1 -root@localhost ~ /etc/fstab +[root@localhost ~]# vi /etc/fstab LABEL=/ / ext3 defaults 1 1 LABEL=/disk1 /disk1 ext3 defaults 1 2 LABEL=/disk2 /disk2 ext3 defaults,usrquota,grpquota 1 2 @@ -57,9 +57,9 @@ LABEL=/disk2 /disk2 ext3 defaults,usrquota,grpquota 1 2 重新`remount filesystem`来驱动设定值。 ``` -root@localhost ~ /dev/hdb1 -root@localhost ~ -a -root@localhost ~ '/disk2' /etc/mtab +[root@localhost ~]# umount /dev/hdb1 +[root@localhost ~]# mount -a +[root@localhost ~]# grep '/disk2' /etc/mtab /dev/hdb1 /disk2 ext3 rw,usrquota,grpquota 0 0 ``` @@ -74,7 +74,7 @@ root@localhost ~ '/disk2' /etc/mtab 扫瞄磁盘的使用者使用状况,并产生重要的 aquota.group 与 aquota.user: ``` -root@localhost ~ -avug +[root@localhost ~]# quotacheck -avug quotacheck: Scanning /dev/hdb1 [/disk2] done quotacheck: Checked 3 directories and 4 files @@ -86,15 +86,15 @@ quotacheck: Checked 3 directories and 4 files 使用 quotacheck 就可以轻易的将所需要的数据给他输出了!但奇怪的是,在某些 Linux 版本中,不能够以 aquota.user(group) 来启动quota ,可能是因为旧版 quota 的关系, 所以就另外做了一个 link 文件按来欺骗 quota,这个动作非必要。(主要是学习这个思维很重要) ``` -root@localhost ~ /disk2 -root@localhost ~ -s aquota.user quota.user +[root@localhost ~]# cd /disk2 +[root@localhost ~]# ln -s aquota.user quota.user [root@localhost ~]# ln -s aquota.group quota.group ``` 启动 quota 的限额: ``` -root@localhost ~ -avug +[root@localhost ~]# quotaon -avug /dev/hdb1 [/disk2]: group quotas turned on /dev/hdb1 [/disk2]: user quotas turned on ===> 看到turned on,才是真的成功! ``` @@ -102,7 +102,7 @@ root@localhost ~ -avug 编辑使用者的可使用空间: ``` -root@localhost ~ -u quser1 +[root@localhost ~]# edquota -u quser1 Disk quotas for user quser1 (uid 502): Filesystem blocks soft hard inodes soft hard /dev/hdb1 0 45000 50000 0 0 0 diff --git a/command/readelf.md b/command/readelf.md new file mode 100644 index 0000000000..13714b5c1e --- /dev/null +++ b/command/readelf.md @@ -0,0 +1,601 @@ +readelf +=== + +用于显示elf格式文件的信息 + +## 补充说明 + +**readelf命令** 用来显示一个或者多个elf格式的目标文件的信息,可以通过它的选项来控制显示哪些信息。这里的elf-file(s)就表示那些被检查的文件。可以支持32位,64位的elf格式文件,也支持包含elf文件的文档(这里一般指的是使用ar命令将一些elf文件打包之后生成的例如lib*.a之类的“静态库”文件)。  + +这个程序和objdump提供的功能类似,但是它显示的信息更为具体,并且它不依赖BFD库(BFD库是一个GNU项目,它的目标就是希望通过一种统一的接口来处理不同的目标文件),所以即使BFD库有什么bug存在的话也不会影响到readelf程序。  + +运行readelf的时候,除了-v和-H之外,其它的选项必须有一个被指定。  + +### ELF文件类型 + + **种类型的ELF文件:** + +1. 可重定位文件:用户和其他目标文件一起创建可执行文件或者共享目标文件,例如lib*.a文件。  +2. 可执行文件:用于生成进程映像,载入内存执行,例如编译好的可执行文件a.out。  +3. 共享目标文件:用于和其他共享目标文件或者可重定位文件一起生成elf目标文件或者和执行文件一起创建进程映像,例如lib*.so文件。  + + **ELF文件作用:** + +ELF文件参与程序的连接(建立一个程序)和程序的执行(运行一个程序),所以可以从不同的角度来看待elf格式的文件:  + +1. 如果用于编译和链接(可重定位文件),则编译器和链接器将把elf文件看作是节头表描述的节的集合,程序头表可选。  +2. 如果用于加载执行(可执行文件),则加载器则将把elf文件看作是程序头表描述的段的集合,一个段可能包含多个节,节头表可选。  +3. 如果是共享文件,则两者都含有。  + + **ELF文件总体组成:**   + +elf文件头描述elf文件的总体信息。包括:系统相关,类型相关,加载相关,链接相关。  + +* 系统相关表示:elf文件标识的魔术数,以及硬件和平台等相关信息,增加了elf文件的移植性,使交叉编译成为可能。  +* 类型相关就是前面说的那个类型。  +* 加载相关:包括程序头表相关信息。  +* 链接相关:节头表相关信息。  + +### 选项 + +``` +-a +--all 显示全部信息,等价于 -h -l -S -s -r -d -V -A -I. + +-h +--file-header 显示elf文件开始的文件头信息. + +-l +--program-headers +--segments 显示程序头(段头)信息(如果有的话)。 + +-S +--section-headers +--sections 显示节头信息(如果有的话)。 + +-g +--section-groups 显示节组信息(如果有的话)。 + +-t +--section-details 显示节的详细信息(-S的)。 + +-s +--syms +--symbols 显示符号表段中的项(如果有的话)。 + +-e +--headers 显示全部头信息,等价于: -h -l -S + +-n +--notes 显示note段(内核注释)的信息。 + +-r +--relocs 显示可重定位段的信息。 + +-u +--unwind 显示unwind段信息。当前只支持IA64 ELF的unwind段信息。 + +-d +--dynamic 显示动态段的信息。 + +-V +--version-info 显示版本段的信息。 + +-A +--arch-specific 显示CPU构架信息。 + +-D +--use-dynamic 使用动态段中的符号表显示符号,而不是使用符号段。 + +-x +--hex-dump= 以16进制方式显示指定段内内容。number指定段表中段的索引,或字符串指定文件中的段名。 + +-w[liaprmfFsoR] or +--debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges] 显示调试段中指定的内容。 + +-I +--histogram 显示符号的时候,显示bucket list长度的柱状图。 + +-v +--version 显示readelf的版本信息。 + +-H +--help 显示readelf所支持的命令行选项。 + +-W +--wide 宽行输出。 + +@file 可以将选项集中到一个文件中,然后使用这个@file选项载入。 +``` + +### 实例 + +先给出如下例子: + + **1.对于可执行文件形式的elf格式文件:** + +1)查看可执行程序的源代码如下:  + +``` +root@localhost [test]$ cat main.cpp +#include +using std::cout; +using std::endl; +void my_print(); + +int main(int argc, char *argv[]) +{ + my_print(); + cout<<"hello!"< +using std::cout; +using std::endl; +void printInfo() +{ + cout<<"hello"< \ No newline at end of file diff --git a/command/reject.md b/command/reject.md new file mode 100644 index 0000000000..c28a60fdbb --- /dev/null +++ b/command/reject.md @@ -0,0 +1,30 @@ +reject +=== + +指示打印系统拒绝发往指定目标打印机的打印任务 + +## 补充说明 + +**reject命令** 属于CUPS套件,用于指示打印系统拒绝发往指定目标打印机的打印任务。 + +### 语法 + +``` +reject(选项)(参数) +``` + +### 选项 + +``` +-E:当连接到服务器时强制使用加密; +-U:指定连接服务器时使用的用户名; +-h:指定连接服务器名和端口号; +-r:指定拒绝打印任务的原因。 +``` + +### 参数 + +目标:指定目标打印机。 + + + \ No newline at end of file diff --git a/command/restorecon.md b/command/restorecon.md index cac35689ae..312ca00752 100644 --- a/command/restorecon.md +++ b/command/restorecon.md @@ -31,18 +31,18 @@ restorecon [-iFnrRv] [-e excludedir ] [-o filename ] [-f filename | pathname...] 假设CentOS安装了apache,网页默认的主目录是`/var/www/html`,我们经常遇到这样的问题,在其他目录中创建了一个网页文件,然后用mv移动到网页默认目录`/var/www/html`中,但是在浏览器中却打不开这个文件,这很可能是因为这个文件的SELinux配置信息是继承原来那个目录的,与`/var/www/html`目录不同,使用mv移动的时候,这个SELinux配置信息也一起移动过来了,从而导致无法打开页面,具体请看下面的实例:
/*使用CentOS举例,如果默认没有安装apache,确保网络连接,使用下面的命令安装*/
-root@linuxde.net ~ install httpd
+[root@jsdig.com ~]# yum install httpd
  /*我们在root的家目录新建一个html文件*/
-root@linuxde.net ~
+[root@jsdig.com ~]# pwd
 /root
 
-root@linuxde.net ~ index.html
+[root@jsdig.com ~]# vi index.html
 
 /*随便输入一段文字,保存退出*/
-welcome to www.linuxde.net
+welcome to www.jsdig.com
 
 /*将这个文件mv到网页默认目录下*/
-[root@linuxde.net ~]# mv index.html /var/www/html/
+[root@jsdig.com ~]# mv index.html /var/www/html/
 
 /*
  * 这个时候我们使用firefox浏览器输入127.0.0.1/index.html发现打不开,
@@ -55,14 +55,14 @@ welcome to www.linuxde.net
 type=AVC msg=audit(1378974214.610:465): avc:  denied  { open } for  pid=2359 comm="httpd" path="/var/www/html/index.html" dev="sda1" ino=1317685 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file
 
 /*使用ls -Z也可以看出,文件和目录的SELinux信息不匹配*/
-[root@linuxde.net html]# ls -Z /var/www/html/
+[root@jsdig.com html]# ls -Z /var/www/html/
 .... unconfined_u:object_r:admin_home_t:s0 index.html
 
-[root@linuxde.net html]# ls -Zd /var/www/html/
+[root@jsdig.com html]# ls -Zd /var/www/html/
 .... system_u:object_r:httpd_sys_content_t:s0 /var/www/html/
 
 /*使用restorecon来恢复网页主目录中所有文件的SELinux配置信息(如果目标为一个目录,可以添加-R参数递归)*/
-[root@linuxde.net html]# restorecon -R /var/www/html/
+[root@jsdig.com html]# restorecon -R /var/www/html/
 ```
 
 
diff --git a/command/rmmod.md b/command/rmmod.md
index af52517993..c5661693eb 100644
--- a/command/rmmod.md
+++ b/command/rmmod.md
@@ -31,7 +31,7 @@ rmmod(选项)(参数)
 用rmmod命令主要用于卸载正在使用的Linux内核模块,与`modprobe -r`命令相似,如下所示:
 
 ```
-root@localhost boot | grep raid1
+[root@localhost boot]# lsmod | grep raid1
 raid1                  25153  0
 
 [root@localhost boot]# rmmod raid1
diff --git a/command/rsync.md b/command/rsync.md
new file mode 100644
index 0000000000..2a0da87359
--- /dev/null
+++ b/command/rsync.md
@@ -0,0 +1,226 @@
+rsync
+===
+
+远程数据同步工具
+
+## 补充说明
+
+**rsync命令** 是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件。rsync使用所谓的“rsync算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快。 rsync是一个功能非常强大的工具,其命令也有很多功能特色选项,我们下面就对它的选项一一进行分析说明。
+
+### 语法  
+
+```
+rsync [OPTION]... SRC DEST
+rsync [OPTION]... SRC [USER@]host:DEST
+rsync [OPTION]... [USER@]HOST:SRC DEST
+rsync [OPTION]... [USER@]HOST::SRC DEST
+rsync [OPTION]... SRC [USER@]HOST::DEST
+rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
+```
+
+对应于以上六种命令格式,rsync有六种不同的工作模式:
+
+1.  拷贝本地文件。当SRC和DES路径信息都不包含有单个冒号":"分隔符时就启动这种工作模式。如:`rsync -a /data /backup`
+2.  使用一个远程shell程序(如rsh、ssh)来实现将本地机器的内容拷贝到远程机器。当DST路径地址包含单个冒号":"分隔符时启动该模式。如:`rsync -avz *.c foo:src`
+3.  使用一个远程shell程序(如rsh、ssh)来实现将远程机器的内容拷贝到本地机器。当SRC地址路径包含单个冒号":"分隔符时启动该模式。如:`rsync -avz foo:src/bar /data`
+4.  从远程rsync服务器中拷贝文件到本地机。当SRC路径信息包含"::"分隔符时启动该模式。如:`rsync -av root@192.168.78.192::www /databack`
+5.  从本地机器拷贝文件到远程rsync服务器中。当DST路径信息包含"::"分隔符时启动该模式。如:`rsync -av /databack root@192.168.78.192::www`
+6.  列远程机的文件列表。这类似于rsync传输,不过只要在命令中省略掉本地机信息即可。如:`rsync -v rsync://192.168.78.192/www`
+
+### 选项  
+
+```
+-v, --verbose 详细模式输出。
+-q, --quiet 精简输出模式。
+-c, --checksum 打开校验开关,强制对文件传输进行校验。
+-a, --archive 归档模式,表示以递归方式传输文件,并保持所有文件属性,等于-rlptgoD。
+-r, --recursive 对子目录以递归模式处理。
+-R, --relative 使用相对路径信息。
+-b, --backup 创建备份,也就是对于目的已经存在有同样的文件名时,将老的文件重新命名为~filename。可以使用--suffix选项来指定不同的备份文件前缀。
+--backup-dir 将备份文件(如~filename)存放在在目录下。
+-suffix=SUFFIX 定义备份文件前缀。
+-u, --update 仅仅进行更新,也就是跳过所有已经存在于DST,并且文件时间晚于要备份的文件,不覆盖更新的文件。
+-l, --links 保留软链结。
+-L, --copy-links 想对待常规文件一样处理软链结。
+--copy-unsafe-links 仅仅拷贝指向SRC路径目录树以外的链结。
+--safe-links 忽略指向SRC路径目录树以外的链结。
+-H, --hard-links 保留硬链结。
+-p, --perms 保持文件权限。
+-o, --owner 保持文件属主信息。
+-g, --group 保持文件属组信息。
+-D, --devices 保持设备文件信息。
+-t, --times 保持文件时间信息。
+-S, --sparse 对稀疏文件进行特殊处理以节省DST的空间。
+-n, --dry-run现实哪些文件将被传输。
+-w, --whole-file 拷贝文件,不进行增量检测。
+-x, --one-file-system 不要跨越文件系统边界。
+-B, --block-size=SIZE 检验算法使用的块尺寸,默认是700字节。
+-e, --rsh=command 指定使用rsh、ssh方式进行数据同步。
+--rsync-path=PATH 指定远程服务器上的rsync命令所在路径信息。
+-C, --cvs-exclude 使用和CVS一样的方法自动忽略文件,用来排除那些不希望传输的文件。
+--existing 仅仅更新那些已经存在于DST的文件,而不备份那些新创建的文件。
+--delete 删除那些DST中SRC没有的文件。
+--delete-excluded 同样删除接收端那些被该选项指定排除的文件。
+--delete-after 传输结束以后再删除。
+--ignore-errors 及时出现IO错误也进行删除。
+--max-delete=NUM 最多删除NUM个文件。
+--partial 保留那些因故没有完全传输的文件,以是加快随后的再次传输。
+--force 强制删除目录,即使不为空。
+--numeric-ids 不将数字的用户和组id匹配为用户名和组名。
+--timeout=time ip超时时间,单位为秒。
+-I, --ignore-times 不跳过那些有同样的时间和长度的文件。
+--size-only 当决定是否要备份文件时,仅仅察看文件大小而不考虑文件时间。
+--modify-window=NUM 决定文件是否时间相同时使用的时间戳窗口,默认为0。
+-T --temp-dir=DIR 在DIR中创建临时文件。
+--compare-dest=DIR 同样比较DIR中的文件来决定是否需要备份。
+-P 等同于 --partial。
+--progress 显示备份过程。
+-z, --compress 对备份的文件在传输时进行压缩处理。
+--exclude=PATTERN 指定排除不需要传输的文件模式。
+--include=PATTERN 指定不排除而需要传输的文件模式。
+--exclude-from=FILE 排除FILE中指定模式的文件。
+--include-from=FILE 不排除FILE指定模式匹配的文件。
+--version 打印版本信息。
+--address 绑定到特定的地址。
+--config=FILE 指定其他的配置文件,不使用默认的rsyncd.conf文件。
+--port=PORT 指定其他的rsync服务端口。
+--blocking-io 对远程shell使用阻塞IO。
+-stats 给出某些文件的传输状态。
+--progress 在传输时现实传输过程。
+--log-format=formAT 指定日志文件格式。
+--password-file=FILE 从FILE中得到密码。
+--bwlimit=KBPS 限制I/O带宽,KBytes per second。
+-h, --help 显示帮助信息。
+```
+
+### 实例  
+
+ **SSH方式** 
+
+首先在服务端启动ssh服务:
+
+```
+service sshd start
+启动 sshd: [确定]
+```
+
+ **使用rsync进行同步** 
+
+接下来就可以在客户端使用rsync命令来备份服务端上的数据了,SSH方式是通过系统用户来进行备份的,如下:
+
+```
+rsync -vzrtopg --progress -e ssh --delete work@172.16.78.192:/www/* /databack/experiment/rsync
+work@172.16.78.192's password:
+receiving file list ...
+5 files to consider
+test/
+a
+0 100% 0.00kB/s 527:35:41 (1, 20.0% of 5)
+b
+67 100% 65.43kB/s 0:00:00 (2, 40.0% of 5)
+c
+0 100% 0.00kB/s 527:35:41 (3, 60.0% of 5)
+dd
+100663296 100% 42.22MB/s 0:00:02 (4, 80.0% of 5)
+sent 96 bytes received 98190 bytes 11563.06 bytes/sec
+total size is 100663363 speedup is 1024.19
+```
+
+上面的信息描述了整个的备份过程,以及总共备份数据的大小。
+
+ **后台服务方式** 
+
+启动rsync服务,编辑`/etc/xinetd.d/rsync`文件,将其中的`disable=yes`改为`disable=no`,并重启xinetd服务,如下:
+
+```
+vi /etc/xinetd.d/rsync
+
+#default: off
+# description: The rsync server is a good addition to an ftp server, as it \
+# allows crc checksumming etc.
+service rsync {
+disable = no
+socket_type = stream
+wait = no
+user = root
+server = /usr/bin/rsync
+server_args = --daemon
+log_on_failure += USERID
+}
+```
+
+```
+/etc/init.d/xinetd restart
+停止 xinetd: [确定]
+启动 xinetd: [确定]
+```
+
+创建配置文件,默认安装好rsync程序后,并不会自动创建rsync的主配置文件,需要手工来创建,其主配置文件为“/etc/rsyncd.conf”,创建该文件并插入如下内容:
+
+```
+vi /etc/rsyncd.conf
+
+uid=root
+gid=root
+max connections=4
+log file=/var/log/rsyncd.log
+pid file=/var/run/rsyncd.pid
+lock file=/var/run/rsyncd.lock
+secrets file=/etc/rsyncd.passwd
+hosts deny=172.16.78.0/22
+
+[www]
+comment= backup web
+path=/www
+read only = no
+exclude=test
+auth users=work
+```
+
+创建密码文件,采用这种方式不能使用系统用户对客户端进行认证,所以需要创建一个密码文件,其格式为“username:password”,用户名可以和密码可以随便定义,最好不要和系统帐户一致,同时要把创建的密码文件权限设置为600,这在前面的模块参数做了详细介绍。
+
+```
+echo "work:abc123" > /etc/rsyncd.passwd
+chmod 600 /etc/rsyncd.passwd
+```
+
+备份,完成以上工作,现在就可以对数据进行备份了,如下:
+
+```
+rsync -avz --progress --delete work@172.16.78.192::www /databack/experiment/rsync
+
+Password:
+receiving file list ...
+6 files to consider
+./ files...
+a
+0 100% 0.00kB/s 528:20:41 (1, 50.0% of 6)
+b
+67 100% 65.43kB/s 0:00:00 (2, 66.7% of 6)
+c
+0 100% 0.00kB/s 528:20:41 (3, 83.3% of 6)
+dd
+100663296 100% 37.49MB/s 0:00:02 (4, 100.0% of 6)
+sent 172 bytes received 98276 bytes 17899.64 bytes/sec
+total size is 150995011 speedup is 1533.75
+```
+
+恢复,当服务器的数据出现问题时,那么这时就需要通过客户端的数据对服务端进行恢复,但前提是服务端允许客户端有写入权限,否则也不能在客户端直接对服务端进行恢复,使用rsync对数据进行恢复的方法如下:
+
+```
+rsync -avz --progress /databack/experiment/rsync/ work@172.16.78.192::www
+
+Password:
+building file list ...
+6 files to consider
+./
+a
+b
+67 100% 0.00kB/s 0:00:00 (2, 66.7% of 6)
+c
+sent 258 bytes received 76 bytes 95.43 bytes/sec
+total size is 150995011 speedup is 452080.87
+```
+
+
+
\ No newline at end of file
diff --git a/command/screen.md b/command/screen.md
index cf1707e214..411909ec69 100644
--- a/command/screen.md
+++ b/command/screen.md
@@ -87,8 +87,8 @@ C-a ] -> paste,把刚刚在 copy mode 选定的内容贴上
 流行的Linux发行版(例如Red Hat Enterprise Linux)通常会自带screen实用程序,如果没有的话,可以从GNU screen的官方网站下载。
 
 ```
-root@TS-DEV ~ install screen
-root@TS-DEV ~ -qa|grep screen
+[root@TS-DEV ~]# yum install screen
+[root@TS-DEV ~]# rpm -qa|grep screen
 screen-4.0.3-4.el5
 [root@TS-DEV ~]#
 ```
@@ -192,7 +192,7 @@ Screen允许使用快捷键C-a s锁定会话。锁定以后,再进行任何输
 在Screen会话之外,可以通过screen命令操作一个Screen会话,这也为使用Screen作为脚本程序增加了便利。关于Screen在脚本中的应用超出了入门的范围,这里只看一个例子,体会一下在会话之外对Screen的操作:
 
 ```
-root@TS-DEV ~ www.baidu.com
+[root@TS-DEV ~]# screen -S sandy -X screen ping www.baidu.com
 ```
 
 这个命令在一个叫做sandy的screen会话中创建一个新窗口,并在其中运行ping命令。
diff --git a/command/sed.md b/command/sed.md
index 8412a28316..59dc7a4226 100644
--- a/command/sed.md
+++ b/command/sed.md
@@ -12,8 +12,8 @@ sed
  **命令格式** 
 
 ```
-sed options' file(s)
-sed options
+sed [options] 'command' file(s)
+sed [options] -f scriptfile file(s)
 ```
 
 ### 选项  
@@ -79,7 +79,7 @@ sed options
  **$**  匹配行结束,如:/sed$/匹配所有以sed结尾的行。
  **.**  匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。
  **** * 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。
- **]ed/匹配sed和Sed。  
+ **[]**  匹配一个指定范围内的字符,如/[ss]ed/匹配sed和Sed。  
  **[^]**  匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
  **\(..\)**  匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。
  **&**  保存搜索字符用来替换其他字符,如s/love/ **&** /,love这成 **love** 。
@@ -199,14 +199,14 @@ sed 's/^192.168.0.1/&localhost/' file
 匹配给定样式的其中一部分:
 
 ```
-echo this is digit 7 in a number | sed 's/digit \(0-9/\1/'
+echo this is digit 7 in a number | sed 's/digit \([0-9]\)/\1/'
 this is 7 in a number
 ```
 
 命令中 digit 7,被替换成了 7。样式匹配到的子串是 7,\(..\) 用于匹配子串,对于匹配到的第一个子串就标记为  **\1** ,依此类推匹配到的第二个结果就是  **\2** ,例如:
 
 ```
-echo aaa BBB | sed 's/\(a-z \(A-Z/\2 \1/'
+echo aaa BBB | sed 's/\([a-z]\+\) \([A-Z]\+\)/\2 \1/'
 BBB aaa
 ```
 
@@ -363,7 +363,7 @@ sed -e '/test/h' -e '/check/x' file
 sed脚本是一个sed的命令清单,启动Sed时以-f选项引导脚本文件名。Sed对于脚本中输入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多个命令,要用分号分隔。以#开头的行为注释行,且不能跨行。
 
 ```
-sed options
+sed [options] -f scriptfile file(s)
 ```
 
 ### 打印奇数行或偶数行  
diff --git a/command/semanage.md b/command/semanage.md
index 4a8c14d0b5..df66c93fa3 100644
--- a/command/semanage.md
+++ b/command/semanage.md
@@ -51,9 +51,9 @@ drwxr-xr-x  root root root:object_r:var_t    /srv/samba
 ```
 semanage fcontext -l | grep '/srv'
 /srv/.*                     all files   system_u:object_r:var_t:s0
-/srv/(^/?ftp(/.*)?     all files   system_u:object_r:public_content_t:s0
-/srv/(^/?www(/.*)?     all files   system_u:object_r:httpd_sys_content_t:s0
-/srv/(^/?rsync(/.*)?   all files   system_u:object_r:public_content_t:s0
+/srv/([^/]*/)?ftp(/.*)?     all files   system_u:object_r:public_content_t:s0
+/srv/([^/]*/)?www(/.*)?     all files   system_u:object_r:httpd_sys_content_t:s0
+/srv/([^/]*/)?rsync(/.*)?   all files   system_u:object_r:public_content_t:s0
 /srv/gallery2(/.*)?         all files   system_u:object_r:httpd_sys_content_t:s0
 /srv                        directory   system_u:object_r:var_t:s0   //看这里!
 ```
diff --git a/command/smbclient.md b/command/smbclient.md
index 64fb1193c6..5342f7c47d 100644
--- a/command/smbclient.md
+++ b/command/smbclient.md
@@ -5,7 +5,7 @@ smbclient
 
 ## 补充说明
 
-**smbclient命** 属于samba套件,它提供一种命令行使用交互式方式访问samba服务器的共享资源。
+**smbclient命令** 属于samba套件,它提供一种命令行使用交互式方式访问samba服务器的共享资源。
 
 ### 语法  
 
@@ -43,13 +43,13 @@ smb服务器:指定要连接的smb服务器。
 
 ### 实例  
 
-**列出某个IP地址所提供的共享文件夹**
+ **列出某个IP地址所提供的共享文件夹** 
 
 ```
 smbclient -L 198.168.0.1 -U username%password
 ```
 
-**像ftp客户端一样使用smbclient**
+ **像ftp客户端一样使用smbclient** 
 
 ```
 smbclient //192.168.0.1/tmp  -U username%password
@@ -59,7 +59,7 @@ smbclient //192.168.0.1/tmp  -U username%password
 
 这里有许多命令和ftp命令相似,如cd 、lcd、get、megt、put、mput等。通过这些命令,我们可以访问远程主机的共享资源。
 
-**直接一次性使用smbclient命令**
+ **直接一次性使用smbclient命令** 
 
 ```
 smbclient -c "ls"  //192.168.0.1/tmp  -U username%password
@@ -74,10 +74,13 @@ smb:/>ls
 
 功能一样的。
 
-**创建一个共享文件夹**
+ **创建一个共享文件夹** 
 
 ```
 smbclient -c "mkdir share1" //192.168.0.1/tmp -U username%password
 ```
 
-如果用户共享`//192.168.0.1/tmp`的方式是只读的,会提示`NT_STATUS_ACCESS_DENIED making remote directory /share1`
\ No newline at end of file
+如果用户共享`//192.168.0.1/tmp`的方式是只读的,会提示`NT_STATUS_ACCESS_DENIED making remote directory /share1`
+
+
+
\ No newline at end of file
diff --git a/command/speedtest-cli.md b/command/speedtest-cli.md
new file mode 100644
index 0000000000..6998e097f9
--- /dev/null
+++ b/command/speedtest-cli.md
@@ -0,0 +1,122 @@
+speedtest-cli
+===
+
+命令行下测试服务器外网速度
+
+## 补充说明
+
+**speedtest-cli** 是一个使用python编写的命令行脚本,通过调用speedtest.net测试上下行的接口来完成速度测试,最后我会测试运维生存时间所在服务器的外网速度。项目地址:https://github.com/sivel/speedtest-cli
+
+### 安装speedtest-cli  
+
+speedtest-cli需要在python 2.4-3.4的环境下,安装方法都很简单,自己选择以下最适合你的一种。
+
+ **pip方式** 
+
+```
+# pip install speedtest-cli
+```
+
+ **easy_install方式** 
+
+```
+# easy_install speedtest-cli
+```
+
+ **github+pip方式** 
+
+```
+# pip install git+https://github.com/sivel/speedtest-cli.git
+```
+
+或者
+
+```
+# git clone https://github.com/sivel/speedtest-cli.git
+# python speedtest-cli/setup.py install
+```
+
+ **下载脚本方式** 
+
+```
+# wget -O speedtest-cli https://raw.github.com/sivel/spe ... er/speedtest_cli.py
+# chmod +x speedtest-cli
+```
+
+或者
+
+```
+# curl -o speedtest-cli https://raw.github.com/sivel/spe ... er/speedtest_cli.py
+# chmod +x speedtest-cli
+```
+
+直接下载脚本,给予执行权限即可。
+
+### 用法  
+
+```
+-h, --help       show this help message and exit
+--share          分享你的网速,该命令会在speedtest网站上生成网速测试结果的图片。
+--simple         Suppress verbose output, only show basic information
+--list           根据距离显示speedtest.net的测试服务器列表。
+--server=SERVER  指定列表中id的服务器来做测试。
+--mini=MINI      URL of the Speedtest Mini server
+--source=SOURCE  Source ip address to bind to
+--version        Show the version number and exit
+```
+
+### 实例  
+
+列出所有在中国的测试服务器:
+
+```
+[root@li229-122 ~]# speedtest-cli --list | grep China
+1185) China Unicom (Changchun, China) [10534.35 km]
+3784) China Mobile (Urumqi, China) [10581.15 km]
+2667) Beijing Normal University (Beijing, China) [11117.03 km]
+2529) Beijing Normal University (Beijing, China) [11117.03 km]
+2816) Capital Online Data service (Beijing, China) [11117.03 km]
+4354) SXmobile (Taiyuan, China) [11383.17 km]
+3973) China Telecom (Lanzhou, China) [11615.43 km]
+3633) China Telecom (Shanghai, China) [11983.37 km]
+3927) China Mobile Jiangsu Co., Ltd. (Suzhou, China) [11989.27 km]
+2461) China Unicom (Chengdu, China) [12213.35 km]
+1028) Shepherd Software (Xiamen, China) [12785.57 km]
+1628) Xiamen Guangdian Xinxu (Xiamen, China) [12785.57 km]
+3891) GZinternet (Guangzhou, China) [13005.36 km]
+3871) SZWCDMA (Shenzhen, China) [13059.20 km]
+3819) SZU (Shenzhen, China) [13059.20 km]
+1536) STC (Hong Kong, China) [13088.37 km]
+1890) Telin (Hong Kong, China) [13088.37 km]
+```
+
+ **结果解释** 
+
+```
+3633) China Telecom (Shanghai, China) [11983.37 km]
+```
+
+```
+3633: 服务器id
+china telecom:isp,这里是中国电信
+shanghai,china :服务器所在地址
+11983.37 km:两台服务器地理位置之间距离,我这台机器在美国,和上海相距11983.37公里,很远呐.
+```
+
+ **外网速度测试** 
+
+```
+[root@li229-122 ~]# speedtest-cli --server=3633 --share
+Retrieving speedtest.net configuration...
+Retrieving speedtest.net server list...
+Testing from Linode (173.255.219.122)...
+Hosted by China Telecom (Shanghai) [11983.37 km]: 23.603 ms
+Testing download speed........................................
+Download: 24.84 Mbit/s
+Testing upload speed..................................................
+Upload: 4.57 Mbit/s
+Share results: http://www.speedtest.net/result/3240988007.png
+```
+
+
+
\ No newline at end of file
diff --git a/command/split.md b/command/split.md
index d43047a9be..e0f303302e 100644
--- a/command/split.md
+++ b/command/split.md
@@ -21,7 +21,7 @@ split
 生成一个大小为100KB的测试文件:
 
 ```
-root@localhost split if=/dev/zero bs=100k count=1 of=date.file
+[root@localhost split]# dd if=/dev/zero bs=100k count=1 of=date.file
 1+0 records in
 1+0 records out
 102400 bytes (102 kB) copied, 0.00043 seconds, 238 MB/s
@@ -31,7 +31,7 @@ root@localhost split if=/dev/zero bs=100k count=1 of=date.file
 
 ```
 [root@localhost split]# split -b 10k date.file 
-root@localhost split
+[root@localhost split]# ls
 date.file  xaa  xab  xac  xad  xae  xaf  xag  xah  xai  xaj
 ```
 
diff --git a/command/startx.md b/command/startx.md
index 5c557b56c4..ad9ad9adac 100644
--- a/command/startx.md
+++ b/command/startx.md
@@ -5,7 +5,7 @@ startx
 
 ## 补充说明
 
-**startx命** 用来启动X Window,实际上启动X Window的程序为xinit。
+**startx命令** 用来启动X Window,实际上启动X Window的程序为xinit。
 
 ### 语法  
 
@@ -85,4 +85,7 @@ $HOME/.twmrc twm 配置文件。
 $HOME/.awmrc awm 配置文件。
 $HOME/.uwmrc uwm 配置文件。
 /dev/lft* 终端或 tty、工作站初始 login shell 的界面。
-```
\ No newline at end of file
+```
+
+
+
\ No newline at end of file
diff --git a/command/sudo.md b/command/sudo.md
index 5df7a34f3e..1072a28f01 100644
--- a/command/sudo.md
+++ b/command/sudo.md
@@ -60,7 +60,7 @@ foobar ALL=(ALL)    ALL
 保存退出后,切换到foobar用户,我们用它的身份执行命令:
 
 ```
-foobar@localhost ~ /root
+[foobar@localhost ~]$ ls /root
 ls: /root: 权限不够
 
 [foobar@localhost ~]$ sudo ls /root
@@ -77,7 +77,7 @@ foobar localhost=    /sbin/ifconfig,   /bin/ls
 再来执行命令:
 
 ```
-foobar@localhost ~ -5 /etc/shadow
+[foobar@localhost ~]$ sudo head -5 /etc/shadow
 Password:
 Sorry, user foobar is not allowed to execute '/usr/bin/head -5 /etc/shadow' as root on localhost.localdomain.
 
diff --git a/command/tee.md b/command/tee.md
index 81ae6d9f29..e5c526e52a 100644
--- a/command/tee.md
+++ b/command/tee.md
@@ -46,7 +46,7 @@ WWW.pef
 ```
 
 ```
-root@localhost text -n
+[root@localhost text]# ls | tee out.txt | cat -n
      1  1.sh
      2  1.txt
      3  2.txt
diff --git a/command/tempfile.md b/command/tempfile.md
new file mode 100644
index 0000000000..409da1d562
--- /dev/null
+++ b/command/tempfile.md
@@ -0,0 +1,39 @@
+tempfile
+===
+
+shell中给临时文件命名
+
+## 补充说明
+
+有时候在写Shell脚本的时候需要一些临时存储数据的才做,最适合存储临时文件数据的位置就是`/tmp`,因为该目录中所有的内容在系统重启后就会被清空。下面是两种方法为临时数据生成标准的文件名。
+
+### tempfile命令  
+
+`tempfile命令`只有在基于Debian的发行版中才默认自带,比如Ubuntu,其他发行版没有这个命令。
+
+用tempfile命令为一个临时文件命名:
+
+```
+temp_file_name=$(tempfile)
+```
+
+用一个加带了随机数的文件名作为临时文件命名:
+
+```
+temp_file_name="/tmp/file_$RANDOM"
+```
+
+$RANDOM是一个返回随机数的环境变量。
+
+### $$变量  
+
+如果没有tempfile命令的Linux发行版,也可以使用自己的临时文件名:
+
+```
+temp_file_name="/tmp/file.$"
+```
+
+`$$`是系统预定义变量,显示当前所在进程的进程号,用`.$$`作为添加的后缀会被扩展成当前运行脚本的进程id。
+
+
+
\ No newline at end of file
diff --git a/command/test.md b/command/test.md
new file mode 100644
index 0000000000..78d05b456c
--- /dev/null
+++ b/command/test.md
@@ -0,0 +1,99 @@
+test
+===
+
+shell环境中测试条件表达式工具
+
+## 补充说明
+
+**test命令** 是shell环境中测试条件表达式的实用工具。
+
+### 语法  
+
+```
+test(选项)
+```
+
+### 选项  
+
+```
+-b<文件>:如果文件为一个块特殊文件,则为真;
+-c<文件>:如果文件为一个字符特殊文件,则为真;
+-d<文件>:如果文件为一个目录,则为真;
+-e<文件>:如果文件存在,则为真;
+-f<文件>:如果文件为一个普通文件,则为真;
+-g<文件>:如果设置了文件的SGID位,则为真;
+-G<文件>:如果文件存在且归该组所有,则为真;
+-k<文件>:如果设置了文件的粘着位,则为真;
+-O<文件>:如果文件存在并且归该用户所有,则为真;
+-p<文件>:如果文件为一个命名管道,则为真;
+-r<文件>:如果文件可读,则为真;
+-s<文件>:如果文件的长度不为零,则为真;
+-S<文件>:如果文件为一个套接字特殊文件,则为真;
+-u<文件>:如果设置了文件的SUID位,则为真;
+-w<文件>:如果文件可写,则为真;
+-x<文件>:如果文件可执行,则为真。
+```
+
+### 实例  
+
+linux中shell编程中的test常见用法:
+
+ **判断表达式** 
+
+```
+if test     #表达式为真
+if test !   #表达式为假
+test 表达式1 –a 表达式2     #两个表达式都为真
+test 表达式1 –o 表达式2     #两个表达式有一个为真
+test 表达式1 ! 表达式2       #条件求反
+```
+
+ **判断字符串** 
+
+```
+test –n 字符串    #字符串的长度非零
+test –z 字符串    #字符串的长度是否为零
+test 字符串1=字符串2       #字符串是否相等,若相等返回true
+test 字符串1!=字符串2      #字符串是否不等,若不等反悔false
+```
+
+ **判断整数** 
+
+```
+test 整数1 -eq 整数2    #整数相等
+test 整数1 -ge 整数2    #整数1大于等于整数2
+test 整数1 -gt 整数2    #整数1大于整数2
+test 整数1 -le 整数2    #整数1小于等于整数2
+test 整数1 -lt 整数2    #整数1小于整数2
+test 整数1 -ne 整数2    #整数1不等于整数2
+```
+
+ **判断文件** 
+
+```
+test File1 –ef File2    两个文件是否为同一个文件,可用于硬连接。主要判断两个文件是否指向同一个inode。
+test File1 –nt File2    判断文件1是否比文件2新
+test File1 –ot File2    判断文件1比是否文件2旧
+test –b file   #文件是否块设备文件
+test –c File   #文件并且是字符设备文件
+test –d File   #文件并且是目录
+test –e File   #文件是否存在 (常用)
+test –f File   #文件是否为正规文件 (常用)
+test –g File   #文件是否是设置了组id
+test –G File   #文件属于的有效组ID
+test –h File   #文件是否是一个符号链接(同-L)
+test –k File   #文件是否设置了Sticky bit位
+test –b File   #文件存在并且是块设备文件
+test –L File   #文件是否是一个符号链接(同-h)
+test –o File   #文件的属于有效用户ID
+test –p File   #文件是一个命名管道
+test –r File   #文件是否可读
+test –s File   #文件是否是非空白文件
+test –t FD     #文件描述符是在一个终端打开的
+test –u File   #文件存在并且设置了它的set-user-id位
+test –w File   #文件是否存在并可写
+test –x File   #文件属否存在并可执行
+```
+
+
+
\ No newline at end of file
diff --git a/command/tftp.md b/command/tftp.md
index 828a384773..bd6ea37d1a 100644
--- a/command/tftp.md
+++ b/command/tftp.md
@@ -136,7 +136,7 @@ tftp your-ip-address
 命令格式为:
 
 ```
-tftp option [port]
+tftp [option] ... host [port]
 ```
 
 如果要下载或上传文件的话是一定要用这些option的。
diff --git a/command/vdfuse.md b/command/vdfuse.md
new file mode 100644
index 0000000000..ff4beeee74
--- /dev/null
+++ b/command/vdfuse.md
@@ -0,0 +1,59 @@
+vdfuse
+===
+
+VirtualBox软件挂载VDI分区文件工具
+
+## 补充说明
+
+**vdfuse命令** 是VirtualBox软件挂载VDI分区文件的一个工具,VirtualBox是一款能创建虚拟机的开源软件,vdi是它的默认磁盘格式。
+
+### 什么是VirtualBox  
+
+VirtualBox是一款功能强大的x86虚拟机软件,它不仅具有丰富的特色,而且性能也很优异。更可喜的是,VirtualBox于数日前走向开源,成为了一个发布在GPL许可之下的自由软件。VirtualBox可以在Linux和Windows主机中运行,并支持在其中安装Windows (NT 4.0、2000、XP、Server 2003、Vista)、DOS/Windows 3.x、Linux (2.4 和 2.6)、OpenBSD等系列的客户操作系统。
+
+ **在Ubuntu中安装vdfuse,打开终端,输入:** 
+
+```
+sudo apt-get install virtualbox-fuse
+```
+
+### 语法  
+
+```
+vdfuse [options] -f image-file mountpoint
+```
+
+### 选项  
+
+```
+-h 帮助
+-r 只读
+-t 类型 (VDI, VMDK, VHD, or raw; default: auto)
+-f 镜像文件
+-a 允许所有用户读取
+-w 允许所有用户都写
+-g 前台运行
+-v 输出反馈
+-d debug模式
+```
+
+注意:必须编辑一下`/etc/fuse.confand`,去掉 "user_allow_other" 前面的注释符号(#),否则不能正确运行。
+
+### 实例  
+
+使用如下如下语句挂载.vdi文件:
+
+```
+sudo vdfuse -f /path/to/file.vdi /path/to/mountpoint
+```
+
+`/path/to/mountpoint`应该包含如下文件EntireDisk、Partition1等,如果只有一个文件,你可能需要这样挂载:
+
+```
+mount /path/to/mountpoint/Partition1 /path/to/someother/mountpoint
+```
+
+文件系统就挂载到`/path/to/someother/mountpoint`了。
+
+
+
\ No newline at end of file
diff --git a/command/wall.md b/command/wall.md
index c516a18f9e..9c60d574bc 100644
--- a/command/wall.md
+++ b/command/wall.md
@@ -5,7 +5,7 @@ wall
 
 ## 补充说明
 
-**wall命** 用于向系统当前所有打开的终端上输出信息。通过wall命令可将信息发送给每位同意接收公众信息的终端机用户,若不给予其信息内容,则wall命令会从标准输入设备读取数据,然后再把所得到的数据传送给所有终端机用户。
+**wall命令** 用于向系统当前所有打开的终端上输出信息。通过wall命令可将信息发送给每位同意接收公众信息的终端机用户,若不给予其信息内容,则wall命令会从标准输入设备读取数据,然后再把所得到的数据传送给所有终端机用户。
 
 ### 语法  
 
@@ -20,9 +20,12 @@ wall(参数)
 ### 实例  
 
 ```
-root@localhost ~ line
+[root@localhost ~]# wall this is a test line
 
 Broadcast message from root (pts/1) (Fri Dec 20 11:36:51 2013):
 
 this is a test line
-```
\ No newline at end of file
+```
+
+
+
\ No newline at end of file
diff --git a/command/wget.md b/command/wget.md
index 4900bde739..d10fb099a5 100644
--- a/command/wget.md
+++ b/command/wget.md
@@ -49,7 +49,7 @@ URL:下载指定的URL地址。
  **使用wget下载单个文件** 
 
 ```
-wget http://www.linuxde.net/testfile.zip
+wget http://www.jsdig.com/testfile.zip
 ```
 
 以下的例子是从网络下载一个文件并保存在当前目录,在下载的过程中会显示进度条,包含(下载完成百分比,已经下载的字节,当前下载速度,剩余下载时间)。
@@ -57,7 +57,7 @@ wget http://www.linuxde.net/testfile.zip
  **下载并以不同的文件名保存** 
 
 ```
-wget -O wordpress.zip http://www.linuxde.net/download.aspx?id=1080
+wget -O wordpress.zip http://www.jsdig.com/download.aspx?id=1080
 ```
 
 wget默认会以最后一个符合`/`的后面的字符来命令,对于动态链接的下载通常文件名会不正确。
@@ -65,7 +65,7 @@ wget默认会以最后一个符合`/`的后面的字符来命令,对于动态
 错误:下面的例子会下载一个文件并以名称`download.aspx?id=1080`保存:
 
 ```
-wget http://www.linuxde.net/download?id=1
+wget http://www.jsdig.com/download?id=1
 ```
 
 即使下载的文件是zip格式,它仍然以`download.php?id=1080`命令。
@@ -73,13 +73,13 @@ wget http://www.linuxde.net/download?id=1
 正确:为了解决这个问题,我们可以使用参数`-O`来指定一个文件名:
 
 ```
-wget -O wordpress.zip http://www.linuxde.net/download.aspx?id=1080
+wget -O wordpress.zip http://www.jsdig.com/download.aspx?id=1080
 ```
 
  **wget限速下载** 
 
 ```
-wget --limit-rate=300k http://www.linuxde.net/testfile.zip
+wget --limit-rate=300k http://www.jsdig.com/testfile.zip
 ```
 
 当你执行wget的时候,它默认会占用全部可能的宽带下载。但是当你准备下载一个大文件,而你还需要下载其它文件时就有必要限速了。
@@ -87,7 +87,7 @@ wget --limit-rate=300k http://www.linuxde.net/testfile.zip
  **使用wget断点续传** 
 
 ```
-wget -c http://www.linuxde.net/testfile.zip
+wget -c http://www.jsdig.com/testfile.zip
 ```
 
 使用`wget -c`重新启动下载中断的文件,对于我们下载大文件时突然由于网络等原因中断非常有帮助,我们可以继续接着下载而不是重新下载一个文件。需要继续中断的下载时可以使用`-c`参数。
@@ -95,7 +95,7 @@ wget -c http://www.linuxde.net/testfile.zip
  **使用wget后台下载** 
 
 ```
-wget -b http://www.linuxde.net/testfile.zip
+wget -b http://www.jsdig.com/testfile.zip
 
 Continuing in background, pid 1840.
 Output will be written to `wget-log'.
@@ -110,7 +110,7 @@ tail -f wget-log
  **伪装代理名称下载** 
 
 ```
-wget --user-agent="Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16" http://www.linuxde.net/testfile.zip
+wget --user-agent="Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16" http://www.jsdig.com/testfile.zip
 ```
 
 有些网站能通过根据判断代理名称不是浏览器而拒绝你的下载请求。不过你可以通过`--user-agent`参数伪装。
diff --git a/command/which.md b/command/which.md
index 77c866542c..3092c4f538 100644
--- a/command/which.md
+++ b/command/which.md
@@ -31,7 +31,7 @@ which(选项)(参数)
 查找文件、显示命令路径:
 
 ```
-root@localhost ~
+[root@localhost ~]# which pwd
 /bin/pwd
 
 [root@localhost ~]#  which adduser
diff --git a/command/xargs.md b/command/xargs.md
new file mode 100644
index 0000000000..210a92b503
--- /dev/null
+++ b/command/xargs.md
@@ -0,0 +1,171 @@
+xargs
+===
+
+给其他命令传递参数的一个过滤器
+
+## 补充说明
+
+**xargs命令** 是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具。它擅长将标准输入数据转换成命令行参数,xargs能够处理管道或者stdin并将其转换成特定命令的命令参数。xargs也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。xargs的默认命令是echo,空格是默认定界符。这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代。xargs是构建单行命令的重要组件之一。
+
+### xargs命令用法  
+
+xargs用作替换工具,读取输入数据重新格式化后输出。
+
+定义一个测试文件,内有多行文本数据:
+
+```
+cat test.txt
+
+a b c d e f g
+h i j k l m n
+o p q
+r s t
+u v w x y z
+
+```
+
+多行输入单行输出:
+
+```
+cat test.txt | xargs
+
+a b c d e f g h i j k l m n o p q r s t u v w x y z
+```
+
+ **-n选项** 多行输出:
+
+```
+cat test.txt | xargs -n3
+
+a b c
+d e f
+g h i
+j k l
+m n o
+p q r
+s t u
+v w x
+y z
+```
+
+ **-d选项** 可以自定义一个定界符:
+
+```
+echo "nameXnameXnameXname" | xargs -dX
+
+name name name name
+```
+
+结合 **-n选项** 使用:
+
+```
+echo "nameXnameXnameXname" | xargs -dX -n2
+
+name name
+name name
+```
+
+ **读取stdin,将格式化后的参数传递给命令** 
+
+假设一个命令为 sk.sh 和一个保存参数的文件arg.txt:
+
+```
+#!/bin/bash
+#sk.sh命令内容,打印出所有参数。
+
+echo $*
+
+```
+
+arg.txt文件内容:
+
+```
+cat arg.txt
+
+aaa
+bbb
+ccc
+
+```
+
+xargs的一个 **选项-I** ,使用-I指定一个替换字符串{},这个字符串在xargs扩展时会被替换掉,当-I与xargs结合使用,每一个参数命令都会被执行一次:
+
+```
+cat arg.txt | xargs -I {} ./sk.sh -p {} -l
+
+-p aaa -l
+-p bbb -l
+-p ccc -l
+
+```
+
+复制所有图片文件到 /data/images 目录下:
+
+```
+ls *.jpg | xargs -n1 -I cp {} /data/images
+```
+
+ **xargs结合find使用** 
+
+用rm 删除太多的文件时候,可能得到一个错误信息:/bin/rm Argument list too long. 用xargs去避免这个问题:
+
+```
+find . -type f -name "*.log" -print0 | xargs -0 rm -f
+```
+
+xargs -0将\0作为定界符。
+
+统计一个源代码目录中所有php文件的行数:
+
+```
+find . -type f -name "*.php" -print0 | xargs -0 wc -l
+```
+
+查找所有的jpg 文件,并且压缩它们:
+
+```
+find . -type f -name "*.jpg" -print | xargs tar -czvf images.tar.gz
+
+```
+
+ **xargs其他应用** 
+
+假如你有一个文件包含了很多你希望下载的URL,你能够使用xargs下载所有链接:
+
+```
+cat url-list.txt | xargs wget -c
+
+```
+
+### 子Shell(Subshells)  
+
+运行一个shell脚本时会启动另一个命令解释器.,就好像你的命令是在命令行提示下被解释的一样,类似于批处理文件里的一系列命令。每个shell脚本有效地运行在父shell(parent shell)的一个子进程里。这个父shell是指在一个控制终端或在一个xterm窗口中给你命令指示符的进程。
+
+```
+cmd1 | ( cmd2; cmd3; cmd4 ) | cmd5
+```
+
+如果cmd2 是cd /,那么就会改变子Shell的工作目录,这种改变只是局限于子shell内部,cmd5则完全不知道工作目录发生的变化。子shell是嵌在圆括号()内部的命令序列,子Shell内部定义的变量为局部变量。
+
+子shell可用于为一组命令设定临时的环境变量:
+
+
COMMAND1
+COMMAND2
+COMMAND3
+(
+  IFS=:
+  PATH=/bin
+  unset TERMINFO
+  set -C
+  shift 5
+  COMMAND4
+  COMMAND5
+  exit 3 # 只是从子shell退出。
+)
+# 父shell不受影响,变量值没有更改。
+COMMAND6
+COMMAND7
+```
+
+
+
\ No newline at end of file