TCPDUMP数据包分析及在服务器维护过程中的作用。windump用法类似。今天特别为了测试tcpdump架设了两个虚拟机,对所述命令进行测试。以达到完全了解tcpdump的目的。环境centos 5 虚拟机用vmware。
tcpdump的选项介绍
-a 将网络地址和广播地址转变成名字;
-d 将匹配信息包的代码以人们能够理解的汇编格式给出;
-dd 将匹配信息包的代码以c语言程序段的格式给出;
-ddd 将匹配信息包的代码以十进制的形式给出;
-e 在输出行打印出数据链路层的头部信息;
-f 将外部的Internet地址以数字的形式打印出来;
-l 使标准输出变为缓冲行形式;
-n 不把网络地址转换成名字;
-t 在输出的每一行不打印时间戳;
-v 输出一个稍微详细的信息,例如在ip包中可以包括ttl和服务类型的信息;
-vv 输出详细的报文信息;
-c 在收到指定的包的数目后,tcpdump就会停止;
-F 从指定的文件中读取表达式,忽略其它的表达式;
-i 指定监听的网络接口;
-r 从指定的文件中读取包(这些包一般通过-w选项产生);
-w 直接将包写入文件中,并不分析和打印出来;
-T 将监听到的包直接解释为指定的类型的报文,常见的类型有rpc (远程过程调用)和snmp(简单网络管理协议;)
tcpdump -nnnv arp 查找ARP攻击时确定攻击原MAC地址时常用。
tcpdump -nnnv udp port 53 DNS服务器53端口受ARP攻击时查看攻击源时用。
tcpdump -nnnv udp and not port 53 可以确定是否有非53端口的大流量UDP攻击
tcpdump -nnnv port 80 and host 192.168.0.1 找出从192.168.0.1的80端口收到或发送的IP包。
tcpdump -nnnv ip host 210.27.48.1 and ! 210.27.48.2 获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包
tcpdump -nnnv host 210.27.48.1 and \ (210.27.48.2 or 210.27.48.3 \) 截获主机210.27.48.1 和主机210.27.48.2 或210.27.48.3的通信
tcpdump -nnnv host ! 192.168.15.129 and ! 192.168.15.130 and dst port 80
捕获除了主机192.168.15.129与192.168.15.130 且到本机目标80端口的数据包。
tcpdump -nnnv src 192.168.15.129 and port 53 捕获由192.168.15.129到本机53端口的数据包。不管是UDP还是TCP
信息参考:Tcpdump命令的使用与示例http://tcpdump.anheng.com.cn/news/24/586.html" target="_blank"> http://tcpdump.anheng.com.cn/news/24/586.html
超级详细Tcpdump 的用法 http://course.51cto.com/art/200512/15473.htm
Linux下的Sniffer Tcpdump的安装和使用http://unix-cd.com/vc/www/28/2007-08/8018.html 注此文中部分命令是错的。
TCPDump使用方法小结 http://softtest.chinaitlab.com/qita/746811.html
TCPDUMP高级用法http://blog.csdn.net/linyt/archive/2007/12/14/1936073.aspx
================================================================================
Linux抓包工具:tcpdump简单使用
简单用法,可以分析soap数据包。
this is probably the easiest way to monitor SOAP messages.
simply use
#tcpdump -i eth0 -A -s 1024 port 80 | tee dump.log
to log all the packet sent to port 80 to dump.log
***********************************************************
今天在尝试TTserver的Http协议接口,为了确定走的协议是否为Http,需要抓包确定一下,
在windows下有很多工具很方便的抓包,linux下只能通过命令行来操作了,下面简单记录一下
tcpdump工具的使用:
//抓包,
tcpdump -nX -s 0 -w cap.raw host 123.123.123.123 and port 2978
//读包
tcpdump -r cap.raw -A
tcpdump有很多参数选项,man就可看到,
-----------------------------------------------------------------------------------
EXAMPLES
To print all packets arriving at or departing from sundown:
tcpdump host sundown
To print traffic between helios and either hot or ace:
tcpdump host helios and \( hot or ace \)
To print all IP packets between ace and any host except helios:
tcpdump ip host ace and not helios
To print all traffic between local hosts and hosts at Berkeley:
tcpdump net ucb-ether
To print all ftp traffic through internet gateway snup: (note that the
expression is quoted to prevent the shell from (mis-)interpreting the
parentheses):
tcpdump 'gateway snup and (port ftp or ftp-data)'
To print traffic neither sourced from nor destined for local hosts (if
you gateway to one other net, this stuff should never make it onto your
local net).
tcpdump ip and not net localnet
To print the start and end packets (the SYN and FIN packets) of each
TCP conversation that involves a non-local host.
tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net localnet'
To print all IPv4 HTTP packets to and from port 80, i.e. print only
packets that contain data, not, for example, SYN and FIN packets and
ACK-only packets. (IPv6 is left as an exercise for the reader.)
tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<>2)) != 0)'
To print IP packets longer than 576 bytes sent through gateway snup:
tcpdump 'gateway snup and ip[2:2] > 576'
To print IP broadcast or multicast packets that were not sent via Eth-
ernet broadcast or multicast:
tcpdump 'ether[0] & 1 = 0 and ip[16] >= 224'
To print all ICMP packets that are not echo requests/replies (i.e., not
ping packets):
tcpdump 'icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply'
------------------------------------------------------------------------------------
注:需要root的权限才能运行tcpdump命令
说实话,tcpdump虽然强大,但是毕竟操作起来不如windows下一些图形软件方便。
tcpdump的选项介绍
-a 将网络地址和广播地址转变成名字;
-d 将匹配信息包的代码以人们能够理解的汇编格式给出;
-dd 将匹配信息包的代码以c语言程序段的格式给出;
-ddd 将匹配信息包的代码以十进制的形式给出;
-e 在输出行打印出数据链路层的头部信息;
-f 将外部的Internet地址以数字的形式打印出来;
-l 使标准输出变为缓冲行形式;
-n 不把网络地址转换成名字;
-t 在输出的每一行不打印时间戳;
-v 输出一个稍微详细的信息,例如在ip包中可以包括ttl和服务类型的信息;
-vv 输出详细的报文信息;
-c 在收到指定的包的数目后,tcpdump就会停止;
-F 从指定的文件中读取表达式,忽略其它的表达式;
-i 指定监听的网络接口;
-r 从指定的文件中读取包(这些包一般通过-w选项产生);
-w 直接将包写入文件中,并不分析和打印出来;
-T 将监听到的包直接解释为指定的类型的报文,常见的类型有rpc (远程过程调用)和snmp(简单网络管理协议;)
tcpdump -nnnv arp 查找ARP攻击时确定攻击原MAC地址时常用。
tcpdump -nnnv udp port 53 DNS服务器53端口受ARP攻击时查看攻击源时用。
tcpdump -nnnv udp and not port 53 可以确定是否有非53端口的大流量UDP攻击
tcpdump -nnnv port 80 and host 192.168.0.1 找出从192.168.0.1的80端口收到或发送的IP包。
tcpdump -nnnv ip host 210.27.48.1 and ! 210.27.48.2 获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包
tcpdump -nnnv host 210.27.48.1 and \ (210.27.48.2 or 210.27.48.3 \) 截获主机210.27.48.1 和主机210.27.48.2 或210.27.48.3的通信
tcpdump -nnnv host ! 192.168.15.129 and ! 192.168.15.130 and dst port 80
捕获除了主机192.168.15.129与192.168.15.130 且到本机目标80端口的数据包。
tcpdump -nnnv src 192.168.15.129 and port 53 捕获由192.168.15.129到本机53端口的数据包。不管是UDP还是TCP
信息参考:Tcpdump命令的使用与示例http://tcpdump.anheng.com.cn/news/24/586.html" target="_blank"> http://tcpdump.anheng.com.cn/news/24/586.html
超级详细Tcpdump 的用法 http://course.51cto.com/art/200512/15473.htm
Linux下的Sniffer Tcpdump的安装和使用http://unix-cd.com/vc/www/28/2007-08/8018.html 注此文中部分命令是错的。
TCPDump使用方法小结 http://softtest.chinaitlab.com/qita/746811.html
TCPDUMP高级用法http://blog.csdn.net/linyt/archive/2007/12/14/1936073.aspx
================================================================================
Linux抓包工具:tcpdump简单使用
简单用法,可以分析soap数据包。
this is probably the easiest way to monitor SOAP messages.
simply use
#tcpdump -i eth0 -A -s 1024 port 80 | tee dump.log
to log all the packet sent to port 80 to dump.log
***********************************************************
今天在尝试TTserver的Http协议接口,为了确定走的协议是否为Http,需要抓包确定一下,
在windows下有很多工具很方便的抓包,linux下只能通过命令行来操作了,下面简单记录一下
tcpdump工具的使用:
//抓包,
tcpdump -nX -s 0 -w cap.raw host 123.123.123.123 and port 2978
//读包
tcpdump -r cap.raw -A
tcpdump有很多参数选项,man就可看到,
-----------------------------------------------------------------------------------
EXAMPLES
To print all packets arriving at or departing from sundown:
tcpdump host sundown
To print traffic between helios and either hot or ace:
tcpdump host helios and \( hot or ace \)
To print all IP packets between ace and any host except helios:
tcpdump ip host ace and not helios
To print all traffic between local hosts and hosts at Berkeley:
tcpdump net ucb-ether
To print all ftp traffic through internet gateway snup: (note that the
expression is quoted to prevent the shell from (mis-)interpreting the
parentheses):
tcpdump 'gateway snup and (port ftp or ftp-data)'
To print traffic neither sourced from nor destined for local hosts (if
you gateway to one other net, this stuff should never make it onto your
local net).
tcpdump ip and not net localnet
To print the start and end packets (the SYN and FIN packets) of each
TCP conversation that involves a non-local host.
tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net localnet'
To print all IPv4 HTTP packets to and from port 80, i.e. print only
packets that contain data, not, for example, SYN and FIN packets and
ACK-only packets. (IPv6 is left as an exercise for the reader.)
tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<>2)) != 0)'
To print IP packets longer than 576 bytes sent through gateway snup:
tcpdump 'gateway snup and ip[2:2] > 576'
To print IP broadcast or multicast packets that were not sent via Eth-
ernet broadcast or multicast:
tcpdump 'ether[0] & 1 = 0 and ip[16] >= 224'
To print all ICMP packets that are not echo requests/replies (i.e., not
ping packets):
tcpdump 'icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply'
------------------------------------------------------------------------------------
注:需要root的权限才能运行tcpdump命令
说实话,tcpdump虽然强大,但是毕竟操作起来不如windows下一些图形软件方便。
虽说都是 *nix 系统,但一个简单的
函数居然用法都不一样。
例如,今天是 2008-6-18
FreeBSD:
输入:date -v -1d +%Y%m%d
输出:20080617
Linux:
输入:date --date='yesterday' +%Y%m%d
输出:20080617
看到这里,会发现,Linux 的局限性,他只能输出昨天的,但前天和大前天的之类的日期就没办法了。
因此,我喜欢FreeBSD就很自然了,呵呵。
函数居然用法都不一样。
例如,今天是 2008-6-18
FreeBSD:
输入:date -v -1d +%Y%m%d
输出:20080617
Linux:
输入:date --date='yesterday' +%Y%m%d
输出:20080617
看到这里,会发现,Linux 的局限性,他只能输出昨天的,但前天和大前天的之类的日期就没办法了。
因此,我喜欢FreeBSD就很自然了,呵呵。
shell 时用$?查看是否执行成功,成功是0,而在函数里是只要有没有成功,那么整个函数的$?就会是1,于是用它和||结合起来可以实现Shell函数是否成功执行的一个判断并提示。
cat fun.sh
sh fun.sh
hello world...\n
ls: cannot access /tmp2: No such file or directory
ls /tmp2 failed
今天重新再翻看了一下shell程序相关的资料。准备重新将shell再提高一下。
将http://seo-dic.com.cn/archives/2496 提到的《Advanced Bash-Scripting Guide》《高级bash脚本编程指南》上附带的源码重新再看一次。
为了方便查看。我将所有的源代码全部导到一个文件中,再一一查看。省去了每次只打开一个脚本的麻烦。同时,将几个经常用的shell脚本函数稍做了下列举。希望后面可以用得到。
find -type f -name "*.sh" -exec cat {} >>sh.all \;
检查目录是否存在,若不存在,则创建相应目录。
# Check for and create datadir if necessary:
if test ! -d $datadir
then
mkdir $datadir
fi
shell参数判断,若不符合则显示使用方式及退出。
E_BADARGS=65
case $# in
0|1) # The vertical bar means "or" in this context.
echo "Usage: `basename $0` old_file_suffix new_file_suffix"
exit $E_BADARGS # If 0 or 1 arg, then bail out.
;;
esac
另例:
E_OPTERR=65
if [ "$#" -eq 0 ]
then # Script needs at least one command-line argument.
echo "Usage $0 -[options a,b,c]"
exit $E_OPTERR
fi
检查是用户是否是root权限的方式:
ROOT_UID=0 # Root has $UID 0.
E_WRONG_USER=65 # Not root?
E_NOSUCHUSER=70
SUCCESS=0
if [ "$UID" -ne "$ROOT_UID" ]
then
echo; echo "Only root can run this script."; echo
exit $E_WRONG_USER
else
echo
echo "You should know better than to run this script, root."
echo "Even root users get the blues... "
echo
fi
进行用户目录判断:
LOG_DIR=/var/log
ROOT_UID=0 # Only users with $UID 0 have root privileges.
LINES=50 # Default number of lines saved.
E_XCD=66 # Can't change directory?
E_NOTROOT=67 # Non-root exit error.
cd $LOG_DIR
if [ `pwd` != "$LOG_DIR" ] # or if [ "$PWD" != "$LOG_DIR" ]
# Not in /var/log?
then
echo "Can't change to $LOG_DIR."
exit $E_XCD
fi # Doublecheck if in right directory, before messing with log file.
cat fun.sh
sh fun.sh
hello world...\n
ls: cannot access /tmp2: No such file or directory
ls /tmp2 failed
今天重新再翻看了一下shell程序相关的资料。准备重新将shell再提高一下。
将http://seo-dic.com.cn/archives/2496 提到的《Advanced Bash-Scripting Guide》《高级bash脚本编程指南》上附带的源码重新再看一次。
为了方便查看。我将所有的源代码全部导到一个文件中,再一一查看。省去了每次只打开一个脚本的麻烦。同时,将几个经常用的shell脚本函数稍做了下列举。希望后面可以用得到。
find -type f -name "*.sh" -exec cat {} >>sh.all \;
检查目录是否存在,若不存在,则创建相应目录。
# Check for and create datadir if necessary:
if test ! -d $datadir
then
mkdir $datadir
fi
shell参数判断,若不符合则显示使用方式及退出。
E_BADARGS=65
case $# in
0|1) # The vertical bar means "or" in this context.
echo "Usage: `basename $0` old_file_suffix new_file_suffix"
exit $E_BADARGS # If 0 or 1 arg, then bail out.
;;
esac
另例:
E_OPTERR=65
if [ "$#" -eq 0 ]
then # Script needs at least one command-line argument.
echo "Usage $0 -[options a,b,c]"
exit $E_OPTERR
fi
检查是用户是否是root权限的方式:
ROOT_UID=0 # Root has $UID 0.
E_WRONG_USER=65 # Not root?
E_NOSUCHUSER=70
SUCCESS=0
if [ "$UID" -ne "$ROOT_UID" ]
then
echo; echo "Only root can run this script."; echo
exit $E_WRONG_USER
else
echo
echo "You should know better than to run this script, root."
echo "Even root users get the blues... "
echo
fi
进行用户目录判断:
LOG_DIR=/var/log
ROOT_UID=0 # Only users with $UID 0 have root privileges.
LINES=50 # Default number of lines saved.
E_XCD=66 # Can't change directory?
E_NOTROOT=67 # Non-root exit error.
cd $LOG_DIR
if [ `pwd` != "$LOG_DIR" ] # or if [ "$PWD" != "$LOG_DIR" ]
# Not in /var/log?
then
echo "Can't change to $LOG_DIR."
exit $E_XCD
fi # Doublecheck if in right directory, before messing with log file.
前几天接手一台parking服务器,发现其流量经常达到上百M,为了进行流量分流。同时启用另两台机器做分流机。
因数据经整改后。可生成静态页面。所以对分流的服务器的系统就没什么要求了。只要可以显示静态网页的服务器即可。
选了两台电信机房及一台浙江机房的服务器。共三台,其中一台,可跑asp程序,用以生成静态页,其他两台一台是windows系统,另一台是linux系统。分别使用iis及apache实现web服务。
主服务器A 从服务器为B、C
架构为
A->B
A->C
数据通过contab及at指令,定时从A服务器自动用rsync实现数据同步。
因流量过大,经观察需要做的细化步骤有:
1.对IIS服务器要将所有的可能加载的dll工具等如7i24/iistracer等全部卸载。同时因是使用做parking服务器,将其所有的404页面做跳转到首页。
2.取消所有的动态执行权限。
3.对iis要注意观察是否会造成类似的CC全链接攻击。
4.对apache需进行重编译。许可超过256个链接数。
5.加入监控。实现跟踪自动化。
经过这几天的跟踪发现几点结论:
1.虽然我使用的目标服务器提供的web服务是基础是基于dns轮循查询方法上的。但从服务器的流量观察来看。每天都有一台机器要承受较大的流量的。即dns轮循实现的负载均衡不见得是实际的流量及响应均衡。
这点的证据是:浙江电信B与厦门电信C的流量明显不对等。
2.因A服务器同时提供udp53端口的查询功能。将所有域名的的dns解析记录直接都轮流指到A/B/C同时A服务器还提供asp服务cpu的负载稍高。
3.经过几天的观察,发现每天能响应的域名查询量差异较大。高时的流量ip>5万低时,只有2万多。
以此备注。rsync在对静态数据的同步化方面,用途明显。适合轻量级的数据同步。
因数据经整改后。可生成静态页面。所以对分流的服务器的系统就没什么要求了。只要可以显示静态网页的服务器即可。
选了两台电信机房及一台浙江机房的服务器。共三台,其中一台,可跑asp程序,用以生成静态页,其他两台一台是windows系统,另一台是linux系统。分别使用iis及apache实现web服务。
主服务器A 从服务器为B、C
架构为
A->B
A->C
数据通过contab及at指令,定时从A服务器自动用rsync实现数据同步。
因流量过大,经观察需要做的细化步骤有:
1.对IIS服务器要将所有的可能加载的dll工具等如7i24/iistracer等全部卸载。同时因是使用做parking服务器,将其所有的404页面做跳转到首页。
2.取消所有的动态执行权限。
3.对iis要注意观察是否会造成类似的CC全链接攻击。
4.对apache需进行重编译。许可超过256个链接数。
5.加入监控。实现跟踪自动化。
经过这几天的跟踪发现几点结论:
1.虽然我使用的目标服务器提供的web服务是基础是基于dns轮循查询方法上的。但从服务器的流量观察来看。每天都有一台机器要承受较大的流量的。即dns轮循实现的负载均衡不见得是实际的流量及响应均衡。
这点的证据是:浙江电信B与厦门电信C的流量明显不对等。
2.因A服务器同时提供udp53端口的查询功能。将所有域名的的dns解析记录直接都轮流指到A/B/C同时A服务器还提供asp服务cpu的负载稍高。
3.经过几天的观察,发现每天能响应的域名查询量差异较大。高时的流量ip>5万低时,只有2万多。
以此备注。rsync在对静态数据的同步化方面,用途明显。适合轻量级的数据同步。
一、构造字符串
直接构造
STR_ZERO=hello
STR_FIRST="i am a string"
STR_SECOND='success'
重复多次
#repeat the first parm($1) by $2 times
strRepeat()
{
local x=$2
if [ "$x" == "" ]; then
x=0
fi
local STR_TEMP=""
while [ $x -ge 1 ];
do
STR_TEMP=`printf "%s%s" "$STR_TEMP" "$1"`
x=`expr $x - 1`
done
echo $STR_TEMP
}
举例:
STR_REPEAT=`strRepeat "$USER_NAME" 3`
echo "repeat = $STR_REPEAT"
二、赋值与拷贝
直接赋值
与构造字符串一样
USER_NAME=terry
从变量赋值
ALIASE_NAME=$USER_NAME
三、联接
直接联接两个字符串
STR_TEMP=`printf "%s%s" "$STR_ZERO" "$USER_NAME"`
使用printf可以进行更复杂的联接
四、求长
求字符数(char)
COUNT_CHAR=`echo "$STR_FIRST" | wc -m`
echo $COUNT_CHAR
求字节数(byte)
COUNT_BYTE=`echo "$STR_FIRST" | wc -c`
echo $COUNT_BYTE
求字数(word)
COUNT_WORD=`echo "$STR_FIRST" | wc -w`
echo $COUNT_WORD
五、比较
相等比较
str1 = str2
不等比较
str1 != str2
举例:
if [ "$USER_NAME" = "terry" ]; then
echo "I am terry"
fi
小于比较
#return 0 if the two string is equal, return 1 if $1 < $2, else 2strCompare() { local x=0 if [ "$1" != "$2" ]; then x=2 localTEMP=`printf "%s\n%s" "$1" "$2"` local TEMP2=`(echo "$1"; echo "$2") |sort` if [ "$TEMP" = "$TEMP2" ]; then x=1 fi fi echo $x }
六、测试
判空
-z str
判非空
-n str
是否为数字
# return 0 if the string is num, otherwise 1
strIsNum()
{
local RET=1
if [ -n "$1" ]; then
local STR_TEMP=`echo "$1" | sed 's/[0-9]//g'`
if [ -z "$STR_TEMP" ]; then
RET=0
fi
fi
echo $RET
}
举例:
if [ -n "$USER_NAME" ]; then
echo "my name is NOT empty"
fi
echo `strIsNum "9980"`
七、分割
以符号+为准,将字符分割为左右两部分
使用sed
举例:
命令 date --rfc-3339 seconds 的输出为
2007-04-14 15:09:47+08:00
取其+左边的部分
date --rfc-3339 seconds | sed 's/+[0-9][0-9]:[0-9][0-9]//g'
输出为
2007-04-14 15:09:47
取+右边的部分
date --rfc-3339 seconds | sed 's/.*+//g'
输出为
08:00
以空格为分割符的字符串分割
使用awk
举例:
STR_FRUIT="Banana 0.89 100"
取第3字段
echo $STR_FRUIT | awk '{ print $3; }'
八、子字符串
字符串1是否为字符串2的子字符串
# return 0 is $1 is substring of $2, otherwise 1
strIsSubstring()
{
local x=1
case "$2" in
*$1*) x=0;;
esac
echo $x
}
Shell字符串截取
一、Linux shell 截取字符变量的前8位,有方法如下:
1.expr substr “$a” 1 8
2.echo $a|awk ‘{print substr(,1,8)}’
3.echo $a|cut -c1-8
4.echo $
5.expr $a : ‘\(.\\).*’
6.echo $a|dd bs=1 count=8 2>/dev/null
二、按指定的字符串截取
1、第一种方法:
* ${varible##*string} 从左向右截取最后一个string后的字符串
* ${varible#*string}从左向右截取第一个string后的字符串
* ${varible%%string*}从右向左截取最后一个string后的字符串
* ${varible%string*}从右向左截取第一个string后的字符串
“*”只是一个通配符可以不要
例子:
$ MYVAR=foodforthought.jpg
$ echo ${MYVAR##*fo}
rthought.jpg
$ echo ${MYVAR#*fo}
odforthought.jpg
2、第二种方法:${varible:n1:n2}:截取变量varible从n1到n2之间的字符串。
可以根据特定字符偏移和长度,使用另一种形式的变量扩展,来选择特定子字符串。试着在 bash 中输入以下行:
$ EXCLAIM=cowabunga
$ echo ${EXCLAIM:0:3}
cow
$ echo ${EXCLAIM:3:7}
abunga
这种形式的字符串截断非常简便,只需用冒号分开来指定起始字符和子字符串长度。
三、按照指定要求分割:
比如获取后缀名
ls -al | cut -d “.” -f2
shell (bash) 比较运算符
运算符 描述 示例
文件比较运算符
-e filename 如果 filename 存在,则为真 [ -e /var/log/syslog ]
-d filename 如果 filename 为目录,则为真 [ -d /tmp/mydir ]
-f filename 如果 filename 为常规文件,则为真 [ -f /usr/bin/grep ]
-L filename 如果 filename 为符号链接,则为真 [ -L /usr/bin/grep ]
-r filename 如果 filename 可读,则为真 [ -r /var/log/syslog ]
-w filename 如果 filename 可写,则为真 [ -w /var/mytmp.txt ]
-x filename 如果 filename 可执行,则为真 [ -L /usr/bin/grep ]
filename1 -nt filename2 如果 filename1 比 filename2 新,则为真 [ /tmp/install/etc/services -nt /etc/services ]
filename1 -ot filename2 如果 filename1 比 filename2 旧,则为真 [ /boot/bzImage -ot arch/i386/boot/bzImage ]
字符串比较运算符 [size=-1](请注意引号的使用,这是防止空格扰乱代码的好方法)
-z string 如果 string 长度为零,则为真 [ -z "$myvar" ]
-n string 如果 string 长度非零,则为真 [ -n "$myvar" ]
string1 = string2 如果 string1 与 string2 相同,则为真 [ "$myvar" = "one two three" ]
string1 != string2 如果 string1 与 string2 不同,则为真 [ "$myvar" != "one two three" ]
算术比较运算符
num1 -eq num2 等于 [ 3 -eq $mynum ]
num1 -ne num2 不等于 [ 3 -ne $mynum ]
num1 -lt num2 小于 [ 3 -lt $mynum ]
num1 -le num2 小于或等于 [ 3 -le $mynum ]
num1 -gt num2 大于 [ 3 -gt $mynum ]
num1 -ge num2 大于或等于 [ 3 -ge $mynum ]
直接构造
STR_ZERO=hello
STR_FIRST="i am a string"
STR_SECOND='success'
重复多次
#repeat the first parm($1) by $2 times
strRepeat()
{
local x=$2
if [ "$x" == "" ]; then
x=0
fi
local STR_TEMP=""
while [ $x -ge 1 ];
do
STR_TEMP=`printf "%s%s" "$STR_TEMP" "$1"`
x=`expr $x - 1`
done
echo $STR_TEMP
}
举例:
STR_REPEAT=`strRepeat "$USER_NAME" 3`
echo "repeat = $STR_REPEAT"
二、赋值与拷贝
直接赋值
与构造字符串一样
USER_NAME=terry
从变量赋值
ALIASE_NAME=$USER_NAME
三、联接
直接联接两个字符串
STR_TEMP=`printf "%s%s" "$STR_ZERO" "$USER_NAME"`
使用printf可以进行更复杂的联接
四、求长
求字符数(char)
COUNT_CHAR=`echo "$STR_FIRST" | wc -m`
echo $COUNT_CHAR
求字节数(byte)
COUNT_BYTE=`echo "$STR_FIRST" | wc -c`
echo $COUNT_BYTE
求字数(word)
COUNT_WORD=`echo "$STR_FIRST" | wc -w`
echo $COUNT_WORD
五、比较
相等比较
str1 = str2
不等比较
str1 != str2
举例:
if [ "$USER_NAME" = "terry" ]; then
echo "I am terry"
fi
小于比较
#return 0 if the two string is equal, return 1 if $1 < $2, else 2strCompare() { local x=0 if [ "$1" != "$2" ]; then x=2 localTEMP=`printf "%s\n%s" "$1" "$2"` local TEMP2=`(echo "$1"; echo "$2") |sort` if [ "$TEMP" = "$TEMP2" ]; then x=1 fi fi echo $x }
六、测试
判空
-z str
判非空
-n str
是否为数字
# return 0 if the string is num, otherwise 1
strIsNum()
{
local RET=1
if [ -n "$1" ]; then
local STR_TEMP=`echo "$1" | sed 's/[0-9]//g'`
if [ -z "$STR_TEMP" ]; then
RET=0
fi
fi
echo $RET
}
举例:
if [ -n "$USER_NAME" ]; then
echo "my name is NOT empty"
fi
echo `strIsNum "9980"`
七、分割
以符号+为准,将字符分割为左右两部分
使用sed
举例:
命令 date --rfc-3339 seconds 的输出为
2007-04-14 15:09:47+08:00
取其+左边的部分
date --rfc-3339 seconds | sed 's/+[0-9][0-9]:[0-9][0-9]//g'
输出为
2007-04-14 15:09:47
取+右边的部分
date --rfc-3339 seconds | sed 's/.*+//g'
输出为
08:00
以空格为分割符的字符串分割
使用awk
举例:
STR_FRUIT="Banana 0.89 100"
取第3字段
echo $STR_FRUIT | awk '{ print $3; }'
八、子字符串
字符串1是否为字符串2的子字符串
# return 0 is $1 is substring of $2, otherwise 1
strIsSubstring()
{
local x=1
case "$2" in
*$1*) x=0;;
esac
echo $x
}
Shell字符串截取
一、Linux shell 截取字符变量的前8位,有方法如下:
1.expr substr “$a” 1 8
2.echo $a|awk ‘{print substr(,1,8)}’
3.echo $a|cut -c1-8
4.echo $
5.expr $a : ‘\(.\\).*’
6.echo $a|dd bs=1 count=8 2>/dev/null
二、按指定的字符串截取
1、第一种方法:
* ${varible##*string} 从左向右截取最后一个string后的字符串
* ${varible#*string}从左向右截取第一个string后的字符串
* ${varible%%string*}从右向左截取最后一个string后的字符串
* ${varible%string*}从右向左截取第一个string后的字符串
“*”只是一个通配符可以不要
例子:
$ MYVAR=foodforthought.jpg
$ echo ${MYVAR##*fo}
rthought.jpg
$ echo ${MYVAR#*fo}
odforthought.jpg
2、第二种方法:${varible:n1:n2}:截取变量varible从n1到n2之间的字符串。
可以根据特定字符偏移和长度,使用另一种形式的变量扩展,来选择特定子字符串。试着在 bash 中输入以下行:
$ EXCLAIM=cowabunga
$ echo ${EXCLAIM:0:3}
cow
$ echo ${EXCLAIM:3:7}
abunga
这种形式的字符串截断非常简便,只需用冒号分开来指定起始字符和子字符串长度。
三、按照指定要求分割:
比如获取后缀名
ls -al | cut -d “.” -f2
shell (bash) 比较运算符
运算符 描述 示例
文件比较运算符
-e filename 如果 filename 存在,则为真 [ -e /var/log/syslog ]
-d filename 如果 filename 为目录,则为真 [ -d /tmp/mydir ]
-f filename 如果 filename 为常规文件,则为真 [ -f /usr/bin/grep ]
-L filename 如果 filename 为符号链接,则为真 [ -L /usr/bin/grep ]
-r filename 如果 filename 可读,则为真 [ -r /var/log/syslog ]
-w filename 如果 filename 可写,则为真 [ -w /var/mytmp.txt ]
-x filename 如果 filename 可执行,则为真 [ -L /usr/bin/grep ]
filename1 -nt filename2 如果 filename1 比 filename2 新,则为真 [ /tmp/install/etc/services -nt /etc/services ]
filename1 -ot filename2 如果 filename1 比 filename2 旧,则为真 [ /boot/bzImage -ot arch/i386/boot/bzImage ]
字符串比较运算符 [size=-1](请注意引号的使用,这是防止空格扰乱代码的好方法)
-z string 如果 string 长度为零,则为真 [ -z "$myvar" ]
-n string 如果 string 长度非零,则为真 [ -n "$myvar" ]
string1 = string2 如果 string1 与 string2 相同,则为真 [ "$myvar" = "one two three" ]
string1 != string2 如果 string1 与 string2 不同,则为真 [ "$myvar" != "one two three" ]
算术比较运算符
num1 -eq num2 等于 [ 3 -eq $mynum ]
num1 -ne num2 不等于 [ 3 -ne $mynum ]
num1 -lt num2 小于 [ 3 -lt $mynum ]
num1 -le num2 小于或等于 [ 3 -le $mynum ]
num1 -gt num2 大于 [ 3 -gt $mynum ]
num1 -ge num2 大于或等于 [ 3 -ge $mynum ]
比较操作符
整数比较
-eq 等于 if [ "$a"-eq "$b"]
-ne 不等于 if [ "$a"-ne "$b"]
-gt 大于 if [ "$a"-gt "$b"]
-ge 大于等于 if [ "$a"-ge "$b"]
-lt 小于 if [ "$a"-lt "$b"]
-le 小于等于 if [ "$a"-le "$b"]
>,<=,>,>= 只能在双括号里使用 if ((”$a”< “$b”))
字符串比较
= 等于 if [ "$a"= "$b"]
== 等于 它和=是同义词
!= 不相等 if [ "$a"!= "$b"]
< 小于,依照ASCII字符排列顺序,if [ "$a"\< "$b"] 注意 ”<”字 符在[ ] 结构里需要转义,或者if [[ "$a"< "$b"]]
> 大于,依照ASCII字符排列顺序,if [ "$a"\> "$b"] 注意 ”>”字 符在[ ] 结构里需要转义,或者if [[ "$a"> "$b"]]
-z 字符串为”null”,即是指字符串长度为零。
-n 字符串不为”null”,即长度不为零.
注意:
1.应该总是用引号把测试字符串引起来,以免引起不必要的错误
2.操作符在[[…]]结构里使用模式匹配.
[[ "$a"== z* ]] # 如果变量$a以字符”z”开始(模式匹配)则为真.
[[ "$a"== "z*"]] # 如果变量$a与z*(字面上的匹配)相等则为真.
整数比较
-eq 等于 if [ "$a"-eq "$b"]
-ne 不等于 if [ "$a"-ne "$b"]
-gt 大于 if [ "$a"-gt "$b"]
-ge 大于等于 if [ "$a"-ge "$b"]
-lt 小于 if [ "$a"-lt "$b"]
-le 小于等于 if [ "$a"-le "$b"]
>,<=,>,>= 只能在双括号里使用 if ((”$a”< “$b”))
字符串比较
= 等于 if [ "$a"= "$b"]
== 等于 它和=是同义词
!= 不相等 if [ "$a"!= "$b"]
< 小于,依照ASCII字符排列顺序,if [ "$a"\< "$b"] 注意 ”<”字 符在[ ] 结构里需要转义,或者if [[ "$a"< "$b"]]
> 大于,依照ASCII字符排列顺序,if [ "$a"\> "$b"] 注意 ”>”字 符在[ ] 结构里需要转义,或者if [[ "$a"> "$b"]]
-z 字符串为”null”,即是指字符串长度为零。
-n 字符串不为”null”,即长度不为零.
注意:
1.应该总是用引号把测试字符串引起来,以免引起不必要的错误
2.操作符在[[…]]结构里使用模式匹配.
[[ "$a"== z* ]] # 如果变量$a以字符”z”开始(模式匹配)则为真.
[[ "$a"== "z*"]] # 如果变量$a与z*(字面上的匹配)相等则为真.
freebsd 命令行下截图的方法
引用:
sudo vidcontrol -p dump.scr
ttyv0是控制台的名字,dump.scr是截屏输出的名字。
如果需要转换成图形格式,需要用一个叫scr2png的工具:
scr2png dump.png
这个工具可以从port安装 (graphics/scr2png) 今天在 delphij 的回帖中看到的,就记录下来分享了。。哈哈
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/18630/showart_1419878.html
引用:
sudo vidcontrol -p dump.scr
ttyv0是控制台的名字,dump.scr是截屏输出的名字。
如果需要转换成图形格式,需要用一个叫scr2png的工具:
scr2png dump.png
这个工具可以从port安装 (graphics/scr2png) 今天在 delphij 的回帖中看到的,就记录下来分享了。。哈哈
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/18630/showart_1419878.html
通过网友介绍,认识了两款在windows下面非常强大但是免费的mysql客户端。
一个是轻量级的选手,HeidiSQL,下载地址是http://www.heidisql.com/download.php,软件只有4M左右,易于使用,如果猜得没错,应该是用delphi或是bcb开发的。
另外一款是重量级选手,是toad for mysql,下载地址为http://www.toadsoft.com/tda/tdaindex.html,这个系列有其它几个数据库系统支持,如oracle,DB2和sql server,安装包比较大,但是安装之后,发现这个工具还是值得深入使用的。可定制性很强,而且还支持换肤,他的官方介绍是home of the world's #1 tool for database developers and DBAs!口气很大,看样子应该表现也不差吧。这两款都是在windows下面的软件,暂时未发现是否有linux下面的版本。对于windows下面的用户,也算有福了。
一个是轻量级的选手,HeidiSQL,下载地址是http://www.heidisql.com/download.php,软件只有4M左右,易于使用,如果猜得没错,应该是用delphi或是bcb开发的。
另外一款是重量级选手,是toad for mysql,下载地址为http://www.toadsoft.com/tda/tdaindex.html,这个系列有其它几个数据库系统支持,如oracle,DB2和sql server,安装包比较大,但是安装之后,发现这个工具还是值得深入使用的。可定制性很强,而且还支持换肤,他的官方介绍是home of the world's #1 tool for database developers and DBAs!口气很大,看样子应该表现也不差吧。这两款都是在windows下面的软件,暂时未发现是否有linux下面的版本。对于windows下面的用户,也算有福了。
DOS命令 (一)MD——建立子目录 1.功能:创建新的子目录 2.类型:内部命令 3.格式:MD[盘符:][路径名]〈子目录名〉 4.使用说明: (1)“盘符”:指定要建立子目录的磁盘驱动器字母 ...
DOS命令
(一)MD——建立子目录
1.功能:创建新的子目录
2.类型:内部命令
3.格式:MD[盘符:][路径名]〈子目录名〉
4.使用说明:
(1)“盘符”:指定要建立子目录的磁盘驱动器字母,若省略,则为当前驱动器;
(2)“路径名”:要建立的子目录的上级目录名,若缺省则建在当前目录下。
例:(1)在C盘的根目录下创建名为FOX的子目录;(2)在FOX子目录下再创建USER子目录。
C:、>MD FOX (在当前驱动器C盘下创建子目录FOX)
C:、>MD FOX 、USER (在FOX 子目录下再创建USER子目录)
(二)CD——改变当前目录
1.功能:显示当前目录
2.类型:内部命令
3.格式:CD[盘符:][路径名][子目录名]
4.使用说明:
(1)如果省略路径和子目录名则显示当前目录;
(2)如采用“CD、”格式,则退回到根目录;
(3)如采用“CD.。”格式则退回到上一级目录。
例:(1)进入到USER子目录;(2)从USER子目录退回到子目录;(3)返回到根目录。
C:、>CD FOX 、USER(进入FOX子目录下的USER子目录)
C:、FOX、USER>CD.。 (退回上一级根目录)
C:、FOX>CD、 (返回到根目录)
C:、>
(三)RD——删除子目录命令
1.功能:从指定的磁盘删除了目录。
2.类型:内部命令
3.格式:RD[盘符:][路径名][子目录名]
4.使用说明:
(1)子目录在删除前必须是空的,也就是说需要先进入该子目录,使用DEL(删除文件的命令)将其子目录下的文件删空,然后再退回到上一级目录,用RD命令删除该了目录本身;
(2)不能删除根目录和当前目录。
例:要求把C盘FOX子目录下的USER子目录删除,操作如下:
第一步:先将USER子目录下的文件删空;
C、>DEL C:、FOX、USER、*。*
第二步,删除USER子目录。
C、>RD C:、FOX、USER
(四)DIR——显示磁盘目录命令
1.功能:显示磁盘目录的内容。
2.类型:内部命令
3.格式:DIR [盘符][路径][/P][/W]
4. 使用说明:/P的使用;当欲查看的目录太多,无法在一屏显示完屏幕会一直往上卷,不容易看清,加上/P参数后,屏幕上会分面一次显示23行的文件信息,然后暂停,并提示;Press any key to continue
/W的使用:加上/W只显示文件名,至于文件大小及建立的日期和时间则都省略。加上参数后,每行可以显示五个文件名。
(五)PATH——路径设置命令
1.功能:设备可执行文件的搜索路径,只对文件有效。
2.类型:内部命令
3.格式:PATH[盘符1]目录[路径名1]{[;盘符2:],〈目录路径名2〉…}
4.使用说明:
(1)当运行一个可执行文件时,DOS会先在当前目录中搜索该文件,若找到则运行之;若找不到该文件,则根据PATH命令所设置的路径,顺序逐条地到目录中搜索该文件;
(2)PATH命令中的路径,若有两条以上,各路径之间以一个分号“;”隔开;
(3)PATH命令有三种使用方法:
PATH[盘符1:][路径1][盘符2:][路径2]…(设定可执行文件的搜索路径)
PATH:(取消所有路径)
PATH:(显示目前所设的路径)
(六)TREE——显示磁盘目录结构命令
1.功能:显示指定驱动器上所有目录路径和这些目录下的所有文件名。
2.类型:外部命令
3.格式:TREE[盘符:][/F][》PRN]
4.使用说明:
(1)使用/F参数时显示所有目录及目录下的所有文件,省略时,只显示目录,不显示目录下的文件;
(2)选用>PRN参数时,则把所列目录及目录中的文件名打印输出。
(七)DELTREE——删除整个目录命令
1.功能:将整个目录及其下属子目录和文件删除。
2.类型:外部命令
3.格式:DELTREE[盘符:]〈路径名〉
4.使用说明:该命令可以一步就将目录及其下的所有文件、子目录、更下层的子目录一并删除,而且不管文件的属性为隐藏、系统或只读,只要该文件位于删除的目录之下,DELTREE都一视同仁,照删不误。使用时务必小心!!!
五、磁盘操作类命令
(一)FORMAT——磁盘格式化命令
1.功能:对磁盘进行格式化,划分磁道和扇区;同时检查出整个磁盘上有无带缺陷的磁道,对坏道加注标记;建立目录区和文件分配表,使磁盘作好接收DOS的准备。
2.类型:外部命令
3.格式:FORMAT〈盘符:〉[/S][/4][/Q]
4.使用说明:
(1)命令后的盘符不可缺省,若对硬盘进行格式化,则会如下列提示:WARNING:ALL DATA ON NON ——REMOVABLE DISK
DRIVE C:WILL BE LOST !
Proceed with Format (Y/N)?
(警告:所有数据在C盘上,将会丢失,确实要继续格式化吗?)
(2)若是对软盘进行格式化,则会如下提示:Insert mew diskette for drive A;
and press ENTER when ready…
(在A驱中插入新盘,准备好后按回车键)。
(3)选用[/S]参数,将把DOS系统文件IO.SYS 、MSDOS.SYS及COMMAND.COM复制到磁盘上,使该磁盘可以做为DOS启动盘。若不选用/S参数,则格式化后的磙盘只能读写信息,而不能做为启动盘;
(4)选用[/4]参数,在1.2MB的高密度软驱中格式化360KB的低密度盘;
(5)选用[/Q]参数,快速格式化,这个参数并不会重新划分磁盘的磁道貌岸然和扇区,只能将磁盘根目录、文件分配表以及引导扇区清成空白,因此,格式化的速度较快。
(6)选用[/U]参数,表示无条件格式化,即破坏原来磁盘上所有数据。不加/U,则为安全格式化,这时先建立一个镜象文件保存原来的FAT表和根目录,必要时可用UNFORRMAT恢复原来的数据。
(二)UNFORMAT恢复格式化命令
1.功能:对进行过格式化误操作丢失数据的磁盘进行恢复。
2.类型:外部命令
3.格式:UNFORMAT〈盘符〉[/L][/U][/P][/TEST]
4.使用说明:用于将被“非破坏性”格式化的磁盘恢复。根目录下被删除的文件或子目录及磁盘的系统扇区(包括FAT、根目录、BOOT扇区及硬盘分区表)受损时,也可以用UNFORMAT来抢救。
(1)选用/L参数列出找到的子目录名称、文件名称、大孝日期等信息,但不会真的做FORMAT工作。
(2)选用/P参数将显示于屏幕的报告(包含/L参数所产生的信息)同时也送到打印机。运行时屏幕会显示:“Print out will be sent to LPT1”
(3)选用/TEST参数只做模拟试验(TEST)不做真正的写入动作。使用此参数屏幕会显示:“Simulation only”
(4)选用/U参数不使用MIRROR映像文件的数据,直接根据磁盘现状进行UNFORMAT。
(5)选用/PSRTN;修复硬盘分区表。
若在盘符之后加上/P、/L、/TEST之一,都相当于使用了/U参数,UNFORMAT会“假设”此时磁盘没有MIRROR映像文件。
注意:UNFORMAT对于刚FORMAT的磁盘,可以完全恢复,但FORMAT后若做了其它数据的写入,则UNFORMAT就不能完整的救回数据了。UNFORMAT并非是万能的,由于使用UNFORMAT会重建FAT与根目录,所以它也具有较高的危险性,操作不当可能会扩大损失,如果仅误删了几个文件或子目录,只需要利用UNDELETE就够了。
DOS命令
(一)MD——建立子目录
1.功能:创建新的子目录
2.类型:内部命令
3.格式:MD[盘符:][路径名]〈子目录名〉
4.使用说明:
(1)“盘符”:指定要建立子目录的磁盘驱动器字母,若省略,则为当前驱动器;
(2)“路径名”:要建立的子目录的上级目录名,若缺省则建在当前目录下。
例:(1)在C盘的根目录下创建名为FOX的子目录;(2)在FOX子目录下再创建USER子目录。
C:、>MD FOX (在当前驱动器C盘下创建子目录FOX)
C:、>MD FOX 、USER (在FOX 子目录下再创建USER子目录)
(二)CD——改变当前目录
1.功能:显示当前目录
2.类型:内部命令
3.格式:CD[盘符:][路径名][子目录名]
4.使用说明:
(1)如果省略路径和子目录名则显示当前目录;
(2)如采用“CD、”格式,则退回到根目录;
(3)如采用“CD.。”格式则退回到上一级目录。
例:(1)进入到USER子目录;(2)从USER子目录退回到子目录;(3)返回到根目录。
C:、>CD FOX 、USER(进入FOX子目录下的USER子目录)
C:、FOX、USER>CD.。 (退回上一级根目录)
C:、FOX>CD、 (返回到根目录)
C:、>
(三)RD——删除子目录命令
1.功能:从指定的磁盘删除了目录。
2.类型:内部命令
3.格式:RD[盘符:][路径名][子目录名]
4.使用说明:
(1)子目录在删除前必须是空的,也就是说需要先进入该子目录,使用DEL(删除文件的命令)将其子目录下的文件删空,然后再退回到上一级目录,用RD命令删除该了目录本身;
(2)不能删除根目录和当前目录。
例:要求把C盘FOX子目录下的USER子目录删除,操作如下:
第一步:先将USER子目录下的文件删空;
C、>DEL C:、FOX、USER、*。*
第二步,删除USER子目录。
C、>RD C:、FOX、USER
(四)DIR——显示磁盘目录命令
1.功能:显示磁盘目录的内容。
2.类型:内部命令
3.格式:DIR [盘符][路径][/P][/W]
4. 使用说明:/P的使用;当欲查看的目录太多,无法在一屏显示完屏幕会一直往上卷,不容易看清,加上/P参数后,屏幕上会分面一次显示23行的文件信息,然后暂停,并提示;Press any key to continue
/W的使用:加上/W只显示文件名,至于文件大小及建立的日期和时间则都省略。加上参数后,每行可以显示五个文件名。
(五)PATH——路径设置命令
1.功能:设备可执行文件的搜索路径,只对文件有效。
2.类型:内部命令
3.格式:PATH[盘符1]目录[路径名1]{[;盘符2:],〈目录路径名2〉…}
4.使用说明:
(1)当运行一个可执行文件时,DOS会先在当前目录中搜索该文件,若找到则运行之;若找不到该文件,则根据PATH命令所设置的路径,顺序逐条地到目录中搜索该文件;
(2)PATH命令中的路径,若有两条以上,各路径之间以一个分号“;”隔开;
(3)PATH命令有三种使用方法:
PATH[盘符1:][路径1][盘符2:][路径2]…(设定可执行文件的搜索路径)
PATH:(取消所有路径)
PATH:(显示目前所设的路径)
(六)TREE——显示磁盘目录结构命令
1.功能:显示指定驱动器上所有目录路径和这些目录下的所有文件名。
2.类型:外部命令
3.格式:TREE[盘符:][/F][》PRN]
4.使用说明:
(1)使用/F参数时显示所有目录及目录下的所有文件,省略时,只显示目录,不显示目录下的文件;
(2)选用>PRN参数时,则把所列目录及目录中的文件名打印输出。
(七)DELTREE——删除整个目录命令
1.功能:将整个目录及其下属子目录和文件删除。
2.类型:外部命令
3.格式:DELTREE[盘符:]〈路径名〉
4.使用说明:该命令可以一步就将目录及其下的所有文件、子目录、更下层的子目录一并删除,而且不管文件的属性为隐藏、系统或只读,只要该文件位于删除的目录之下,DELTREE都一视同仁,照删不误。使用时务必小心!!!
五、磁盘操作类命令
(一)FORMAT——磁盘格式化命令
1.功能:对磁盘进行格式化,划分磁道和扇区;同时检查出整个磁盘上有无带缺陷的磁道,对坏道加注标记;建立目录区和文件分配表,使磁盘作好接收DOS的准备。
2.类型:外部命令
3.格式:FORMAT〈盘符:〉[/S][/4][/Q]
4.使用说明:
(1)命令后的盘符不可缺省,若对硬盘进行格式化,则会如下列提示:WARNING:ALL DATA ON NON ——REMOVABLE DISK
DRIVE C:WILL BE LOST !
Proceed with Format (Y/N)?
(警告:所有数据在C盘上,将会丢失,确实要继续格式化吗?)
(2)若是对软盘进行格式化,则会如下提示:Insert mew diskette for drive A;
and press ENTER when ready…
(在A驱中插入新盘,准备好后按回车键)。
(3)选用[/S]参数,将把DOS系统文件IO.SYS 、MSDOS.SYS及COMMAND.COM复制到磁盘上,使该磁盘可以做为DOS启动盘。若不选用/S参数,则格式化后的磙盘只能读写信息,而不能做为启动盘;
(4)选用[/4]参数,在1.2MB的高密度软驱中格式化360KB的低密度盘;
(5)选用[/Q]参数,快速格式化,这个参数并不会重新划分磁盘的磁道貌岸然和扇区,只能将磁盘根目录、文件分配表以及引导扇区清成空白,因此,格式化的速度较快。
(6)选用[/U]参数,表示无条件格式化,即破坏原来磁盘上所有数据。不加/U,则为安全格式化,这时先建立一个镜象文件保存原来的FAT表和根目录,必要时可用UNFORRMAT恢复原来的数据。
(二)UNFORMAT恢复格式化命令
1.功能:对进行过格式化误操作丢失数据的磁盘进行恢复。
2.类型:外部命令
3.格式:UNFORMAT〈盘符〉[/L][/U][/P][/TEST]
4.使用说明:用于将被“非破坏性”格式化的磁盘恢复。根目录下被删除的文件或子目录及磁盘的系统扇区(包括FAT、根目录、BOOT扇区及硬盘分区表)受损时,也可以用UNFORMAT来抢救。
(1)选用/L参数列出找到的子目录名称、文件名称、大孝日期等信息,但不会真的做FORMAT工作。
(2)选用/P参数将显示于屏幕的报告(包含/L参数所产生的信息)同时也送到打印机。运行时屏幕会显示:“Print out will be sent to LPT1”
(3)选用/TEST参数只做模拟试验(TEST)不做真正的写入动作。使用此参数屏幕会显示:“Simulation only”
(4)选用/U参数不使用MIRROR映像文件的数据,直接根据磁盘现状进行UNFORMAT。
(5)选用/PSRTN;修复硬盘分区表。
若在盘符之后加上/P、/L、/TEST之一,都相当于使用了/U参数,UNFORMAT会“假设”此时磁盘没有MIRROR映像文件。
注意:UNFORMAT对于刚FORMAT的磁盘,可以完全恢复,但FORMAT后若做了其它数据的写入,则UNFORMAT就不能完整的救回数据了。UNFORMAT并非是万能的,由于使用UNFORMAT会重建FAT与根目录,所以它也具有较高的危险性,操作不当可能会扩大损失,如果仅误删了几个文件或子目录,只需要利用UNDELETE就够了。
$().ready(
function()
{
var a = $('<div style="display:none"><div class="car_img1" id="bloomup2"><iframe src="/con/default/act/cardkindsintro" frameborder="0" scrolling="no" style="width:659px; height:438px"></iframe></div></div>');
$('body').append(a);//添加到body元素的最后.
}
);
function()
{
var a = $('<div style="display:none"><div class="car_img1" id="bloomup2"><iframe src="/con/default/act/cardkindsintro" frameborder="0" scrolling="no" style="width:659px; height:438px"></iframe></div></div>');
$('body').append(a);//添加到body元素的最后.
}
);
Cookie注意事项
1、SetCookie()之前不能有任何html输出,它认了第二,没有哪个元素敢认第一,就是空格,空白行都不行。
2、 SetCookie()后,你在当前页调用echo $_COOKIE["name"]不会有输出。必须刷新或到下一个页面才可以看到Cookie值。原因很简单。SetCookie()执行之后,往客户端发送一个cookie,你不刷新或浏览下一个页面,客户端怎么把cookie给你送回去呀?浏览器创建了一个Cookie后,对于每一个针对该网站的请求,都会在Header中带着这个Cookie;不过,对于其他网站的请求Cookie是绝对不会跟着发送的。而且浏览器会这样一直发送,直到 Cookie过期为止。
bool setcookie (string $name [, string $value [, int $expire [, string $path [, string $domain [, bool $secure]]]]] )
其中中括号内可以省略
$name 参数为Cookie变量名
$value 参数为COOkie值
$expire Cookie的失效时间 ,$expire是标准的UNIX时间标记,可以用time()函数或者mktime()函数获取,单位为秒,如:time()+3600*24*30表示Cookie的有效期为一个月,如果不进行设置默认为会话期间,即关闭浏览器时Cookie失效!
$path Cookie在服务器的有效路径
$domain Cookie有效域名
$secure 指明Cookie是否仅通过安全的HTTPS值为0或1,如果为1,则cookie只能在HTTPS连接有效;如果值为默认值0,则在HTTP和HTTPS连接上均有效
阅读全文
1、SetCookie()之前不能有任何html输出,它认了第二,没有哪个元素敢认第一,就是空格,空白行都不行。
2、 SetCookie()后,你在当前页调用echo $_COOKIE["name"]不会有输出。必须刷新或到下一个页面才可以看到Cookie值。原因很简单。SetCookie()执行之后,往客户端发送一个cookie,你不刷新或浏览下一个页面,客户端怎么把cookie给你送回去呀?浏览器创建了一个Cookie后,对于每一个针对该网站的请求,都会在Header中带着这个Cookie;不过,对于其他网站的请求Cookie是绝对不会跟着发送的。而且浏览器会这样一直发送,直到 Cookie过期为止。
bool setcookie (string $name [, string $value [, int $expire [, string $path [, string $domain [, bool $secure]]]]] )
其中中括号内可以省略
$name 参数为Cookie变量名
$value 参数为COOkie值
$expire Cookie的失效时间 ,$expire是标准的UNIX时间标记,可以用time()函数或者mktime()函数获取,单位为秒,如:time()+3600*24*30表示Cookie的有效期为一个月,如果不进行设置默认为会话期间,即关闭浏览器时Cookie失效!
$path Cookie在服务器的有效路径
$domain Cookie有效域名
$secure 指明Cookie是否仅通过安全的HTTPS值为0或1,如果为1,则cookie只能在HTTPS连接有效;如果值为默认值0,则在HTTP和HTTPS连接上均有效

cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业。由于Cron 是Linux的内置服务,但它不自动起来,可以用以下的方法启动、关闭这个服务:
/sbin/service crond start //启动服务
/sbin/service crond stop //关闭服务
/sbin/service crond restart //重启服务
/sbin/service crond reload //重新载入配置
你也可以将这个服务在系统启动的时候自动启动:
在/etc/rc.d/rc.local这个脚本的末尾加上:
现在Cron这个服务已经在进程里面了,我们就可以用这个服务了,Cron服务提供以下几种接口供大家使用:
1、直接用crontab命令编辑
cron服务提供crontab命令来设定cron服务的,以下是这个命令的一些参数与说明:
比如说root查看自己的cron设置:crontab -u root -l
再例如,root想删除fred的cron设置:crontab -u fred -r
在编辑cron服务时,编辑的内容有一些格式和约定,输入:crontab -u root -e
进入vi编辑模式,编辑的内容一定要符合下面的格式:*/1 * * * * ls >> /tmp/ls.txt
这个格式的前一部分是对时间的设定,后面一部分是要执行的命令,如果要执行的命令太多,可以把这些命令写到一个脚本里面,然后在这里直接调用这个脚本就可以了,调用的时候记得写出命令的完整路径。时间的设定我们有一定的约定,前面五个*号代表五个数字,数字的取值范围和含义如下:
分钟 (0-59)
小時 (0-23)
日期 (1-31)
月份 (1-12)
星期 (0-6)//0代表星期天
除了数字还有几个个特殊的符号就是"*"、"/"和"-"、",",*代表所有的取值范围内的数字,"/"代表每的意思,"*/5"表示每5个单位,"-"代表从某个数字到某个数字,","分开几个离散的数字。以下举几个例子说明问题:
每天早上6点
每两个小时
晚上11点到早上8点之间每两个小时,早上八点
每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
1月1日早上4点
0 4 1 1 * command line
每次编辑完某个用户的cron设置后,cron自动在/var/spool/cron下生成一个与此用户同名的文件,此用户的cron信息都记录在这个文件中,这个文件是不可以直接编辑的,只可以用crontab -e 来编辑。cron启动后每过一份钟读一次这个文件,检查是否要执行里面的命令。因此此文件修改后不需要重新启动cron服务。
2、编辑/etc/crontab 文件配置cron
cron服务每分钟不仅要读一次/var/spool/cron内的所有文件,还需要读一次/etc/crontab,因此我们配置这个文件也能运用 cron服务做一些事情。用crontab配置是针对某个用户的,而编辑/etc/crontab是针对系统的任务。此文件的文件格式是:
大家注意"run-parts"这个参数了,如果去掉这个参数的话,后面就可以写要运行的某个脚本名,而不是文件夹名了。
--------------------------------------
基本格式 :
* * * * * command
分 时 日 月 周 命令
第1列表示分钟1~59 每分钟用*或者 */1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令
crontab文件的一些例子:
30 21 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每晚的21:30重启lighttpd 。
45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每月1、10、22日的4 : 45重启lighttpd 。
10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每周六、周日的1 : 10重启lighttpd 。
0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启lighttpd 。
0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每星期六的11 : 00 pm重启lighttpd 。
* */1 * * * /usr/local/etc/rc.d/lighttpd restart
每一小时重启lighttpd
* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart
晚上11点到早上7点之间,每隔一小时重启lighttpd
0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart
每月的4号与每周一到周三的11点重启lighttpd
0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart
一月一号的4点重启lighttpd
/sbin/service crond start //启动服务
/sbin/service crond stop //关闭服务
/sbin/service crond restart //重启服务
/sbin/service crond reload //重新载入配置
你也可以将这个服务在系统启动的时候自动启动:
在/etc/rc.d/rc.local这个脚本的末尾加上:
/sbin/service crond start
现在Cron这个服务已经在进程里面了,我们就可以用这个服务了,Cron服务提供以下几种接口供大家使用:
1、直接用crontab命令编辑
cron服务提供crontab命令来设定cron服务的,以下是这个命令的一些参数与说明:
crontab -u //设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数
crontab -l //列出某个用户cron服务的详细内容
crontab -r //删除某个用户的cron服务
crontab -e //编辑某个用户的cron服务
crontab -l //列出某个用户cron服务的详细内容
crontab -r //删除某个用户的cron服务
crontab -e //编辑某个用户的cron服务
比如说root查看自己的cron设置:crontab -u root -l
再例如,root想删除fred的cron设置:crontab -u fred -r
在编辑cron服务时,编辑的内容有一些格式和约定,输入:crontab -u root -e
进入vi编辑模式,编辑的内容一定要符合下面的格式:*/1 * * * * ls >> /tmp/ls.txt
这个格式的前一部分是对时间的设定,后面一部分是要执行的命令,如果要执行的命令太多,可以把这些命令写到一个脚本里面,然后在这里直接调用这个脚本就可以了,调用的时候记得写出命令的完整路径。时间的设定我们有一定的约定,前面五个*号代表五个数字,数字的取值范围和含义如下:
分钟 (0-59)
小時 (0-23)
日期 (1-31)
月份 (1-12)
星期 (0-6)//0代表星期天
除了数字还有几个个特殊的符号就是"*"、"/"和"-"、",",*代表所有的取值范围内的数字,"/"代表每的意思,"*/5"表示每5个单位,"-"代表从某个数字到某个数字,","分开几个离散的数字。以下举几个例子说明问题:
每天早上6点
0 6 * * * echo "Good morning." >> /tmp/test.txt //注意单纯echo,从屏幕上看不到任何输出,因为cron把任何输出都email到
root的信箱了。每两个小时
0 */2 * * * echo "Have a break now." >> /tmp/test.txt
晚上11点到早上8点之间每两个小时,早上八点
0 23-7/2,8 * * * echo "Have a good dream:)" >> /tmp/test.txt
每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
0 11 4 * 1-3 command line
1月1日早上4点
0 4 1 1 * command line
每次编辑完某个用户的cron设置后,cron自动在/var/spool/cron下生成一个与此用户同名的文件,此用户的cron信息都记录在这个文件中,这个文件是不可以直接编辑的,只可以用crontab -e 来编辑。cron启动后每过一份钟读一次这个文件,检查是否要执行里面的命令。因此此文件修改后不需要重新启动cron服务。
2、编辑/etc/crontab 文件配置cron
cron服务每分钟不仅要读一次/var/spool/cron内的所有文件,还需要读一次/etc/crontab,因此我们配置这个文件也能运用 cron服务做一些事情。用crontab配置是针对某个用户的,而编辑/etc/crontab是针对系统的任务。此文件的文件格式是:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root //如果出现错误,或者有数据输出,数据作为邮件发给这个帐号
HOME=/ //使用者运行的路径,这里是根目录
# run-parts
01 * * * * root run-parts /etc/cron.hourly //每小时执行/etc/cron.hourly内的脚本
02 4 * * * root run-parts /etc/cron.daily //每天执行/etc/cron.daily内的脚本
22 4 * * 0 root run-parts /etc/cron.weekly //每星期执行/etc/cron.weekly内的脚本
42 4 1 * * root run-parts /etc/cron.monthly //每月去执行/etc/cron.monthly内的脚本
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root //如果出现错误,或者有数据输出,数据作为邮件发给这个帐号
HOME=/ //使用者运行的路径,这里是根目录
# run-parts
01 * * * * root run-parts /etc/cron.hourly //每小时执行/etc/cron.hourly内的脚本
02 4 * * * root run-parts /etc/cron.daily //每天执行/etc/cron.daily内的脚本
22 4 * * 0 root run-parts /etc/cron.weekly //每星期执行/etc/cron.weekly内的脚本
42 4 1 * * root run-parts /etc/cron.monthly //每月去执行/etc/cron.monthly内的脚本
大家注意"run-parts"这个参数了,如果去掉这个参数的话,后面就可以写要运行的某个脚本名,而不是文件夹名了。
--------------------------------------
基本格式 :
* * * * * command
分 时 日 月 周 命令
第1列表示分钟1~59 每分钟用*或者 */1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令
crontab文件的一些例子:
30 21 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每晚的21:30重启lighttpd 。
45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每月1、10、22日的4 : 45重启lighttpd 。
10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每周六、周日的1 : 10重启lighttpd 。
0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启lighttpd 。
0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每星期六的11 : 00 pm重启lighttpd 。
* */1 * * * /usr/local/etc/rc.d/lighttpd restart
每一小时重启lighttpd
* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart
晚上11点到早上7点之间,每隔一小时重启lighttpd
0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart
每月的4号与每周一到周三的11点重启lighttpd
0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart
一月一号的4点重启lighttpd
进一步学习请看vim发布的帮助文档
VIM常用操作
k
h l
J
当前光标位置插入 i
所在行首位置插入 I
当前光标位置后面插入 a
在行尾编辑 A
当前行下面另起一新行 o
当前行上面另起一新行 O
删除换行符 J (即把一行连接到当前行)
删除光标所在字符 x
删除光标所在前一个字符 X
删除整行 dd
删除到行尾 D
删除当前光标所在字符后编辑 s
退格 Ctrl-h
删除当前行后编辑 S
撤消 u ,可以撤消多次
重做 Ctrl + R
重复上一个改变 . (Dot)
查前当前字的man页 相当于执行 : !man
屏幕左下角非空白处 L
屏幕中间非空白处 M
屏幕左上角非空白处 H
向后移动一个word的开头 W, w (这两个有稍微的区别,W 以空白区分字)
向前移动一个word B, b(这两个有稍微的区别)
移到当前word的最后一个字符 e
移动到当前行行尾 $
移动到当前行的第一个 ^
非空白字符上
移动到当前行的第一个字符上 0 (zero)
单字符搜索命令(向右) f : 命令"fx"在当前行上查找下一个字符x
单字符搜索命令(向左) F
跳转到匹配的括号去 % 包括 { } [ ] ( ) 具体可以处理哪 些括号可以
由'matchpairs'选项来定义: help mps
跳转到第一行 gg (or 1G)
跳转到最后一行 G
跳转到第 n 行 nG 如 5G
跳转到文件的百分之N行 N% 如 90%跳到接近文件尾的地方
移动到当前窗口的中间 M
当前在文件中的位置 CTRL-G
向上滚动半屏 CTRL-U
向下滚动半屏 CTRL-D
向上滚动一屏 CTRL-B
向下滚动一屏 CTRL-F
将光标所在行调整至页面中间 zz
下卷一行 Ctrl+e
上卷一行 Ctrl+y
简单搜索(向后) 如 /include 搜索单词 "include"
简单搜索(向前) 如 ?include
查找当前单词的下一个位置 *
查找当前单词的上一个位置 #
Visual模式
V (整行的选择)
Ctrl-v 选择一个区域内容
Shift-v 选择一个矩行区域
光标后粘贴 p
光标前粘贴 P
复制一行 Y
复制 y (需加一行辅助如 y3w 复制3个单词)
寄存器复制(a-z) 如复制3行放到寄存器 a中 "a3Y
寄存器粘贴 "aP
复制到剪切版 "+y
剪切到剪切版 "+x
从剪切版粘贴 "+gp
只读方式打开文件 Vim -R filename
折叠
环境变量 foldmethod 有6种值 manual、indent、expr、syntax、diff、marker
对着折叠的行展开 0 (Zero)
创建折叠区域 zf 后加上移动指令,如 zfj、 zf5k等
在括号处zf%,创建从当前行起到对应的匹配的括号上去((),{},[],<>等)。
折叠 zc
对所在范围内所有嵌套的 zC
折叠点展开折叠
展开折叠 zo
对所在范围内所有嵌套的 zO
处展开折叠
到当前打开的折叠的开始处。 [z
到当前打开的折叠的末尾处。 ]z
向下移动。到达下一个折叠的 zj
开始处。关闭的折叠也被计入。
向上移动到前一折叠的结束处。 zk
关闭的折叠也被计入。
删除 (delete) 在光标下的 zd (仅当 'foldmethod' 设为 "manual" 或 "marker" 时有效。)
折叠。
循环删除 (Delete) 光标下 zD (仅当 'foldmethod' 设为 "manual" 或 "marker" 时有效。)
的折叠,即嵌套删除折叠。
除去 (Eliminate) 窗口里 zE (仅当 'foldmethod' 设为 "manual" 或 "marker" 时有效。)
“所有”的折叠
窗口操作
水平分隔 split
垂直分隔 vsplit
新建一个窗口 new
关闭当前窗口 close
关闭其它窗口 only
增加当前窗口高度 Ctrl+W +
减小当前窗口高度 Ctrl+W -
指定固定高度 {height}Ctrl+W _
切换活动窗口 Ctrl+W w 或 Ctrl+W Ctrl+W
到左边窗口 Ctrl+W h
到右边窗口 Ctrl+W l
到上边窗口 Ctrl+W k
到下边窗口 Ctrl+W j
到顶部窗口 Ctrl+W t
到底部窗口 Ctrl+W b
排版
向右缩进 >>
向左缩进 <<
右移当前行所在的{....} >i}
内的所有代码(不含"{"和"}")
一个shiftwidth个空格
<i{ 相反 <i} 一样效果
右移当前行所在的{....} >a}
内的所有代码(含"{"和"}")
一个shiftwidth个空格
<a{ 相反 <a} 一样效果
大小写转换
行小写 guu
行大写 gUU
行翻转 g~~
标签页Vim在7以后的版本,开始支持标签页的功能
新建一个标签 :tabnew
转到下一个标签 :tabnext
转到上一个标签 :tabprevious
标签 mark--方便跳来跳去
m 标签指令,mx把当前位置标为x, x 可为 a-z A-Z
'x 跳至标签为 x 所在行的行首非空白处
`x 跳至标签为 x 所在行标签时的位置
编辑多个文件
:n 下一个文件
:N 上一个文件
:first 第一个文件
:last 最后一个文件
:qa 全部退出
映射表
:map Normal, Visual and Operator-pending
:vmap Visual
:nmap Normal
:omap Operator-pending
:map! Insert and Command-line
:imap Insert
:cmap Command-line
<silent> 不在命令行上显示该映射
例子:
映射< 为 <>
:imap < x<Esc>r<a><Esc>ha
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xuzhihong_gdut/archive/2009/01/15/3788220.aspx
VIM常用操作
k
h l
J
当前光标位置插入 i
所在行首位置插入 I
当前光标位置后面插入 a
在行尾编辑 A
当前行下面另起一新行 o
当前行上面另起一新行 O
删除换行符 J (即把一行连接到当前行)
删除光标所在字符 x
删除光标所在前一个字符 X
删除整行 dd
删除到行尾 D
删除当前光标所在字符后编辑 s
退格 Ctrl-h
删除当前行后编辑 S
撤消 u ,可以撤消多次
重做 Ctrl + R
重复上一个改变 . (Dot)
查前当前字的man页 相当于执行 : !man
屏幕左下角非空白处 L
屏幕中间非空白处 M
屏幕左上角非空白处 H
向后移动一个word的开头 W, w (这两个有稍微的区别,W 以空白区分字)
向前移动一个word B, b(这两个有稍微的区别)
移到当前word的最后一个字符 e
移动到当前行行尾 $
移动到当前行的第一个 ^
非空白字符上
移动到当前行的第一个字符上 0 (zero)
单字符搜索命令(向右) f : 命令"fx"在当前行上查找下一个字符x
单字符搜索命令(向左) F
跳转到匹配的括号去 % 包括 { } [ ] ( ) 具体可以处理哪 些括号可以
由'matchpairs'选项来定义: help mps
跳转到第一行 gg (or 1G)
跳转到最后一行 G
跳转到第 n 行 nG 如 5G
跳转到文件的百分之N行 N% 如 90%跳到接近文件尾的地方
移动到当前窗口的中间 M
当前在文件中的位置 CTRL-G
向上滚动半屏 CTRL-U
向下滚动半屏 CTRL-D
向上滚动一屏 CTRL-B
向下滚动一屏 CTRL-F
将光标所在行调整至页面中间 zz
下卷一行 Ctrl+e
上卷一行 Ctrl+y
简单搜索(向后) 如 /include 搜索单词 "include"
简单搜索(向前) 如 ?include
查找当前单词的下一个位置 *
查找当前单词的上一个位置 #
Visual模式
V (整行的选择)
Ctrl-v 选择一个区域内容
Shift-v 选择一个矩行区域
光标后粘贴 p
光标前粘贴 P
复制一行 Y
复制 y (需加一行辅助如 y3w 复制3个单词)
寄存器复制(a-z) 如复制3行放到寄存器 a中 "a3Y
寄存器粘贴 "aP
复制到剪切版 "+y
剪切到剪切版 "+x
从剪切版粘贴 "+gp
只读方式打开文件 Vim -R filename
折叠
环境变量 foldmethod 有6种值 manual、indent、expr、syntax、diff、marker
对着折叠的行展开 0 (Zero)
创建折叠区域 zf 后加上移动指令,如 zfj、 zf5k等
在括号处zf%,创建从当前行起到对应的匹配的括号上去((),{},[],<>等)。
折叠 zc
对所在范围内所有嵌套的 zC
折叠点展开折叠
展开折叠 zo
对所在范围内所有嵌套的 zO
处展开折叠
到当前打开的折叠的开始处。 [z
到当前打开的折叠的末尾处。 ]z
向下移动。到达下一个折叠的 zj
开始处。关闭的折叠也被计入。
向上移动到前一折叠的结束处。 zk
关闭的折叠也被计入。
删除 (delete) 在光标下的 zd (仅当 'foldmethod' 设为 "manual" 或 "marker" 时有效。)
折叠。
循环删除 (Delete) 光标下 zD (仅当 'foldmethod' 设为 "manual" 或 "marker" 时有效。)
的折叠,即嵌套删除折叠。
除去 (Eliminate) 窗口里 zE (仅当 'foldmethod' 设为 "manual" 或 "marker" 时有效。)
“所有”的折叠
窗口操作
水平分隔 split
垂直分隔 vsplit
新建一个窗口 new
关闭当前窗口 close
关闭其它窗口 only
增加当前窗口高度 Ctrl+W +
减小当前窗口高度 Ctrl+W -
指定固定高度 {height}Ctrl+W _
切换活动窗口 Ctrl+W w 或 Ctrl+W Ctrl+W
到左边窗口 Ctrl+W h
到右边窗口 Ctrl+W l
到上边窗口 Ctrl+W k
到下边窗口 Ctrl+W j
到顶部窗口 Ctrl+W t
到底部窗口 Ctrl+W b
排版
向右缩进 >>
向左缩进 <<
右移当前行所在的{....} >i}
内的所有代码(不含"{"和"}")
一个shiftwidth个空格
<i{ 相反 <i} 一样效果
右移当前行所在的{....} >a}
内的所有代码(含"{"和"}")
一个shiftwidth个空格
<a{ 相反 <a} 一样效果
大小写转换
行小写 guu
行大写 gUU
行翻转 g~~
标签页Vim在7以后的版本,开始支持标签页的功能
新建一个标签 :tabnew
转到下一个标签 :tabnext
转到上一个标签 :tabprevious
标签 mark--方便跳来跳去
m 标签指令,mx把当前位置标为x, x 可为 a-z A-Z
'x 跳至标签为 x 所在行的行首非空白处
`x 跳至标签为 x 所在行标签时的位置
编辑多个文件
:n 下一个文件
:N 上一个文件
:first 第一个文件
:last 最后一个文件
:qa 全部退出
映射表
:map Normal, Visual and Operator-pending
:vmap Visual
:nmap Normal
:omap Operator-pending
:map! Insert and Command-line
:imap Insert
:cmap Command-line
<silent> 不在命令行上显示该映射
例子:
映射< 为 <>
:imap < x<Esc>r<a><Esc>ha
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xuzhihong_gdut/archive/2009/01/15/3788220.aspx
无意间想看一下各个门户网站所使用的编码,于是习惯性的用自己写的HTTP调试工具来看。
新浪、网易、搜狐这中国互联网原生的3个大佬,都是gb2312的页面编码。
web服务器方面来看,网易用了nginx,sohu和sina用的是apache,sina是2.0,sohu是1.3
web服务器架构上来看,三个都用了squid来做前端缓冲,至于是否使用负载均衡的软硬件就无法探测得知了。
从此可见,技术领先上,网易第一,新浪次之,sohu最土。而从他们的经营情况来看,也是这个排序。
互联网是一个新技术几乎每时每刻都出现的行业领域,每一次有重大的新技术出现,如果能对现有环境产生巨大改变的,那必然会造就一个时代的英雄出来,网易是,borland是,Google是,就连微软和Oracle都是,占据技术制高点,是成功的法宝!IT企业在技术方面的投入多少,也侧面反映了他们能走到的高度情况。当然这里的前提是非盲目性投资,盲目的投资就像土财主买了个MBA证书一样的可笑。
后话,至于UTF8编码他们都没采用,也能想得通,如果全更换为UTF8,他们的带宽和系统负载需要提高将近一倍,而他们的受众群体都是华人,明显得不偿失。
新浪、网易、搜狐这中国互联网原生的3个大佬,都是gb2312的页面编码。
web服务器方面来看,网易用了nginx,sohu和sina用的是apache,sina是2.0,sohu是1.3
web服务器架构上来看,三个都用了squid来做前端缓冲,至于是否使用负载均衡的软硬件就无法探测得知了。
从此可见,技术领先上,网易第一,新浪次之,sohu最土。而从他们的经营情况来看,也是这个排序。
互联网是一个新技术几乎每时每刻都出现的行业领域,每一次有重大的新技术出现,如果能对现有环境产生巨大改变的,那必然会造就一个时代的英雄出来,网易是,borland是,Google是,就连微软和Oracle都是,占据技术制高点,是成功的法宝!IT企业在技术方面的投入多少,也侧面反映了他们能走到的高度情况。当然这里的前提是非盲目性投资,盲目的投资就像土财主买了个MBA证书一样的可笑。
后话,至于UTF8编码他们都没采用,也能想得通,如果全更换为UTF8,他们的带宽和系统负载需要提高将近一倍,而他们的受众群体都是华人,明显得不偿失。
404不正确页面的优势可能在于不用调用Rewrite模块,Rewrite须要调用此模块。因此404不正确页面可能会更节省资源,使大型站点的速度更快一些。我编写的静态化网页,目前大多数都是运用 404不正确。
运用 404不正确页面,不能被POST和GET。例如305.php?name1=auiou,假如此305.php页面是用404不正确产生,则此$_GET["name1"]的值不会被读取。其它页面的
运用 POST要领将action指向此404不正确产生的305.php,也不能被接收,例如所发送的信息不能被305.php接收。
如果您希望产生的虚拟路径如305.php被POST和GET,运用 Rewrite可处理。
404不正确页面的开头有一些Linux空间必须写入这句,有一些Linux空间则必须写为才可以被搜索引擎收入,否则会被认为是404页面。调试时,可以在网上搜索“404 检测工具”执行 测试。
Rewrite能不能须要写语句,我还没有测试过。
404不正确页面的准则相对不严格,因此有更好的适应范围。Rewrite相对更严格,例如305.html与305-1.html须要写2个重写准则;运用 404不正确页面只要一个准则即可。这也是我运用 404不正确,而不运用 Rewrite的另一个主要原由。
我是这么写的:
RewriteRule /con/user/act/gift [L,R=404]
[L,R=404]// # NOTE! FOR APACHE ON WINDOWS
运用 404不正确页面,不能被POST和GET。例如305.php?name1=auiou,假如此305.php页面是用404不正确产生,则此$_GET["name1"]的值不会被读取。其它页面的
运用 POST要领将action指向此404不正确产生的305.php,也不能被接收,例如所发送的信息不能被305.php接收。
如果您希望产生的虚拟路径如305.php被POST和GET,运用 Rewrite可处理。
404不正确页面的开头有一些Linux空间必须写入这句,有一些Linux空间则必须写为才可以被搜索引擎收入,否则会被认为是404页面。调试时,可以在网上搜索“404 检测工具”执行 测试。
Rewrite能不能须要写语句,我还没有测试过。
404不正确页面的准则相对不严格,因此有更好的适应范围。Rewrite相对更严格,例如305.html与305-1.html须要写2个重写准则;运用 404不正确页面只要一个准则即可。这也是我运用 404不正确,而不运用 Rewrite的另一个主要原由。
#RewriteRule ^(.*)$ [L,r=404]
#RewriteRule ^(.*)$ - [L,r=404]
RewriteRule ^(.*)$ /error404.html [L,r=404]
#RewriteRule ^(.*)$ - [L,r=404]
RewriteRule ^(.*)$ /error404.html [L,r=404]
我是这么写的:
RewriteRule /con/user/act/gift [L,R=404]
为了使Apache更加平滑地从1.3版升级到2.0版,Apache开发团队做了很多工作。目前很多重要的模块已经可以很好地支持2.0版,如PHP、FastCGI、Mod_perl、Mod_python等。在httpd.conf的指令配置语法上,目前的2.0版(2.0.45)与1.3版的兼容性已做得相当好。比如,以前的2.0版如果要使用PHP,一般用过滤器实现;现在的PHP官方文档中已经使用1.3版中的LoadModule语句做为加载PHP的推荐方式。只要略微了解一下Apache 2.0的新特性,从1.3版升级到2.0版将是一件非常容易的事情。使用Apache 2.0是大势所趋,因为Apache的开发团队已经把开发重心转移到2.0版上。1.3版自2002年10月发布了1.3.27后一直没有新版本推出,而2.0版在与1.3.27同时发布2.0.43后,在今年1月发布了2.0.44,并于今年3月末发布了2.0.45,并包含了很多改进和修正。
MPM的引入带来性能改善
Apache 2.0在性能上的改善最吸引人。在支持POSIX线程的Unix系统上,Apache可以通过不同的MPM运行在一种多进程与多线程相混合的模式下,增强部分配置的可扩充性能。相比于Apache 1.3,2.0版本做了大量的优化来提升处理能力和可伸缩性,并且大多数改进在默认状态下即可生效。但是在编译和运行时刻,2.0也有许多可以显著提高性能的选择。本文不想叙述那些以功能换取速度的指令,如HostnameLookups等,而只是说明在2.0中影响性能的最核心特性:MPM(Multi-Processing Modules,多道处理模块)的基本工作原理和配置指令。
毫不夸张地说,MPM的引入是Apache 2.0最重要的变化。大家知道,Apache是基于模块化的设计,而Apache 2.0更扩展了模块化设计到Web服务器的最基本功能。服务器装载了一种多道处理模块,负责绑定本机网络端口、接受请求,并调度子进程来处理请求。扩展模块化设计有两个重要好处:
◆ Apache可以更简洁、有效地支持多种操作系统;
◆ 服务器可以按站点的特殊需要进行自定制。
在用户级,MPM看起来和其它Apache模块非常类似。主要区别是在任意时刻只能有一种MPM被装载到服务器中。
指定MPM的方法
下面以Red Hat Linux 9为平台,说明在Apache 2.0中如何指定MPM (Apache采用2.0.45)。先解压缩源代码包httpd-2.0.45.tar.gz,生成httpd-2.0.45目录(Apache 1.3源代码包的命名规则是apache_1.3.NN.tar.gz,而2.0版则是httpd-2.0.NN.tar.gz,其中NN是次版本号)。
进入httpd-2.0.45目录,运行以下代码:
显示如下:
上述操作用来选择要使用的进程模型,即哪种MPM模块。Beos、mpmt_os2分别是BeOS和OS/2上缺省的MPM,perchild主要设计目的是以不同的用户和组的身份来运行不同的子进程。这在运行多个需要CGI的虚拟主机时特别有用,会比1.3版中的SuExec机制做得更好。leader和threadpool都是基于worker的变体,还处于实验性阶段,某些情况下并不会按照预期设想的那样工作,所以Apache官方也并不推荐使用。因此,我们主要阐述prefork和worker这两种和性能关系最大的产品级MPM ( 有关其它的MPM详细说明,请参见Apache官方文档:http://httpd.apache.org/docs-2.0/mod/)。
prefork的工作原理及配置
如果不用“--with-mpm”显式指定某种MPM,prefork就是Unix平台上缺省的MPM。它所采用的预派生子进程方式也是Apache 1.3中采用的模式。prefork本身并没有使用到线程,2.0版使用它是为了与1.3版保持兼容性;另一方面,prefork用单独的子进程来处理不同的请求,进程之间是彼此独立的,这也使其成为最稳定的MPM之一。
若使用prefork,在make编译和make install安装后,使用“httpd -l”来确定当前使用的MPM,应该会看到prefork.c(如果看到worker.c说明使用的是worker MPM,依此类推)。再查看缺省生成的httpd.conf配置文件,里面包含如下配置段:
prefork的工作原理是,控制进程在最初建立“StartServers”个子进程后,为了满足MinSpareServers设置的需要创建一个进程,等待一秒钟,继续创建两个,再等待一秒钟,继续创建四个……如此按指数级增加创建的进程数,最多达到每秒32个,直到满足MinSpareServers设置的值为止。这就是预派生(prefork)的由来。这种模式可以不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能。
MaxSpareServers设置了最大的空闲进程数,如果空闲进程数大于这个值,Apache会自动kill掉一些多余进程。这个值不要设得过大,但如果设的值比MinSpareServers小,Apache会自动把其调整为MinSpareServers+1。如果站点负载较大,可考虑同时加大MinSpareServers和MaxSpareServers。
MaxRequestsPerChild设置的是每个子进程可处理的请求数。每个子进程在处理了“MaxRequestsPerChild”个请求后将自动销毁。0意味着无限,即子进程永不销毁。虽然缺省设为0可以使每个子进程处理更多的请求,但如果设成非零值也有两点重要的好处:
◆ 可防止意外的内存泄漏;
◆ 在服务器负载下降的时侯会自动减少子进程数。
因此,可根据服务器的负载来调整这个值。笔者认为10000左右比较合适。
MaxClients是这些指令中最为重要的一个,设定的是Apache可以同时处理的请求,是对Apache性能影响最大的参数。其缺省值150是远远不够的,如果请求总数已达到这个值(可通过ps -ef|grep http|wc -l来确认),那么后面的请求就要排队,直到某个已处理请求完毕。这就是系统资源还剩下很多而HTTP访问却很慢的主要原因。系统管理员可以根据硬件配置和负载情况来动态调整这个值。虽然理论上这个值越大,可以处理的请求就越多,但Apache默认的限制不能大于256。如果把这个值设为大于256,那么Apache将无法起动。事实上,256对于负载稍重的站点也是不够的。在Apache 1.3中,这是个硬限制。如果要加大这个值,必须在“configure”前手工修改的源代码树下的src/include/httpd.h中查找256,就会发现“#define HARD_SERVER_LIMIT 256”这行。把256改为要增大的值(如4000),然后重新编译Apache即可。在Apache 2.0中新加入了ServerLimit指令,使得无须重编译Apache就可以加大MaxClients。下面是笔者的prefork配置段:
上述配置中,ServerLimit的最大值是20000,对于大多数站点已经足够。如果一定要再加大这个数值,对位于源代码树下server/mpm/prefork/prefork.c中以下两行做相应修改即可:
worker的工作原理及配置
相对于prefork,worker是2.0 版中全新的支持多线程和多进程混合模型的MPM。由于使用线程来处理,钥梢源硐喽院A康那肭螅低匙试吹目∮诨诮痰姆衿鳌5牵瑆orker也使用了多进程,每个进程又生成多个线程,以获得基于进程服务器的稳定性。这种MPM的工作方式将是Apache 2.0的发展趋势。
在configure -with-mpm=worker后,进行make编译、make install安装。在缺省生成的httpd.conf中有以下配置段:
worker的工作原理是,由主控制进程生成“StartServers”个子进程,每个子进程中包含固定的ThreadsPerChild线程数,各个线程独立地处理请求。同样,为了不在请求到来时再生成线程,MinSpareThreads和MaxSpareThreads设置了最少和最多的空闲线程数;而MaxClients设置了所有子进程中的线程总数。如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程。
MinSpareThreads和MaxSpareThreads的最大缺省值分别是75和250。这两个参数对Apache的性能影响并不大,可以按照实际情况相应调节。
ThreadsPerChild是worker MPM中与性能相关最密切的指令。ThreadsPerChild的最大缺省值是64,如果负载较大,64也是不够的。这时要显式使用ThreadLimit指令,它的最大缺省值是20000。上述两个值位于源码树server/mpm/worker/worker.c中的以下两行:
这两行对应着ThreadsPerChild和ThreadLimit的限制数。最好在configure之前就把64改成所希望的值。注意,不要把这两个值设得太高,超过系统的处理能力,从而因Apache不起动使系统很不稳定。
Worker模式下所能同时处理的请求总数是由子进程总数乘以ThreadsPerChild值决定的,应该大于等于MaxClients。如果负载很大,现有的子进程数不能满足时,控制进程会派生新的子进程。默认最大的子进程总数是16,加大时也需要显式声明ServerLimit(最大值是20000)。这两个值位于源码树server/mpm/worker/worker.c中的以下两行:
需要注意的是,如果显式声明了ServerLimit,那么它乘以ThreadsPerChild的值必须大于等于MaxClients,而且MaxClients必须是ThreadsPerChild的整数倍,否则Apache将会自动调节到一个相应值(可能是个非期望值)。下面是笔者的worker配置段:
<IfModule worker.c>
StartServers 3
MaxClients 2000
ServerLimit 25
MinSpareThreads 50
MaxSpareThreads 200
ThreadLimit 200
ThreadsPerChild 100
MaxRequestsPerChild 0
</IfModule>
通过上面的叙述,可以了解到Apache 2.0中prefork和worker这两个重要MPM的工作原理,并可根据实际情况来配置Apache相关的核心参数,以获得最大的性能和稳定性。
我的配置:
MPM的引入带来性能改善
Apache 2.0在性能上的改善最吸引人。在支持POSIX线程的Unix系统上,Apache可以通过不同的MPM运行在一种多进程与多线程相混合的模式下,增强部分配置的可扩充性能。相比于Apache 1.3,2.0版本做了大量的优化来提升处理能力和可伸缩性,并且大多数改进在默认状态下即可生效。但是在编译和运行时刻,2.0也有许多可以显著提高性能的选择。本文不想叙述那些以功能换取速度的指令,如HostnameLookups等,而只是说明在2.0中影响性能的最核心特性:MPM(Multi-Processing Modules,多道处理模块)的基本工作原理和配置指令。
毫不夸张地说,MPM的引入是Apache 2.0最重要的变化。大家知道,Apache是基于模块化的设计,而Apache 2.0更扩展了模块化设计到Web服务器的最基本功能。服务器装载了一种多道处理模块,负责绑定本机网络端口、接受请求,并调度子进程来处理请求。扩展模块化设计有两个重要好处:
◆ Apache可以更简洁、有效地支持多种操作系统;
◆ 服务器可以按站点的特殊需要进行自定制。
在用户级,MPM看起来和其它Apache模块非常类似。主要区别是在任意时刻只能有一种MPM被装载到服务器中。
指定MPM的方法
下面以Red Hat Linux 9为平台,说明在Apache 2.0中如何指定MPM (Apache采用2.0.45)。先解压缩源代码包httpd-2.0.45.tar.gz,生成httpd-2.0.45目录(Apache 1.3源代码包的命名规则是apache_1.3.NN.tar.gz,而2.0版则是httpd-2.0.NN.tar.gz,其中NN是次版本号)。
进入httpd-2.0.45目录,运行以下代码:
$ ./configure --help|grep mpm
显示如下:
--with-mpm=MPM Choose the process model for Apache to use. MPM={beos|worker|prefork|mpmt_os2| perchild|leader|threadpool}
上述操作用来选择要使用的进程模型,即哪种MPM模块。Beos、mpmt_os2分别是BeOS和OS/2上缺省的MPM,perchild主要设计目的是以不同的用户和组的身份来运行不同的子进程。这在运行多个需要CGI的虚拟主机时特别有用,会比1.3版中的SuExec机制做得更好。leader和threadpool都是基于worker的变体,还处于实验性阶段,某些情况下并不会按照预期设想的那样工作,所以Apache官方也并不推荐使用。因此,我们主要阐述prefork和worker这两种和性能关系最大的产品级MPM ( 有关其它的MPM详细说明,请参见Apache官方文档:http://httpd.apache.org/docs-2.0/mod/)。
prefork的工作原理及配置
如果不用“--with-mpm”显式指定某种MPM,prefork就是Unix平台上缺省的MPM。它所采用的预派生子进程方式也是Apache 1.3中采用的模式。prefork本身并没有使用到线程,2.0版使用它是为了与1.3版保持兼容性;另一方面,prefork用单独的子进程来处理不同的请求,进程之间是彼此独立的,这也使其成为最稳定的MPM之一。
若使用prefork,在make编译和make install安装后,使用“httpd -l”来确定当前使用的MPM,应该会看到prefork.c(如果看到worker.c说明使用的是worker MPM,依此类推)。再查看缺省生成的httpd.conf配置文件,里面包含如下配置段:
<IfModule prefork.c>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
</IfModule>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
</IfModule>
prefork的工作原理是,控制进程在最初建立“StartServers”个子进程后,为了满足MinSpareServers设置的需要创建一个进程,等待一秒钟,继续创建两个,再等待一秒钟,继续创建四个……如此按指数级增加创建的进程数,最多达到每秒32个,直到满足MinSpareServers设置的值为止。这就是预派生(prefork)的由来。这种模式可以不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能。
MaxSpareServers设置了最大的空闲进程数,如果空闲进程数大于这个值,Apache会自动kill掉一些多余进程。这个值不要设得过大,但如果设的值比MinSpareServers小,Apache会自动把其调整为MinSpareServers+1。如果站点负载较大,可考虑同时加大MinSpareServers和MaxSpareServers。
MaxRequestsPerChild设置的是每个子进程可处理的请求数。每个子进程在处理了“MaxRequestsPerChild”个请求后将自动销毁。0意味着无限,即子进程永不销毁。虽然缺省设为0可以使每个子进程处理更多的请求,但如果设成非零值也有两点重要的好处:
◆ 可防止意外的内存泄漏;
◆ 在服务器负载下降的时侯会自动减少子进程数。
因此,可根据服务器的负载来调整这个值。笔者认为10000左右比较合适。
MaxClients是这些指令中最为重要的一个,设定的是Apache可以同时处理的请求,是对Apache性能影响最大的参数。其缺省值150是远远不够的,如果请求总数已达到这个值(可通过ps -ef|grep http|wc -l来确认),那么后面的请求就要排队,直到某个已处理请求完毕。这就是系统资源还剩下很多而HTTP访问却很慢的主要原因。系统管理员可以根据硬件配置和负载情况来动态调整这个值。虽然理论上这个值越大,可以处理的请求就越多,但Apache默认的限制不能大于256。如果把这个值设为大于256,那么Apache将无法起动。事实上,256对于负载稍重的站点也是不够的。在Apache 1.3中,这是个硬限制。如果要加大这个值,必须在“configure”前手工修改的源代码树下的src/include/httpd.h中查找256,就会发现“#define HARD_SERVER_LIMIT 256”这行。把256改为要增大的值(如4000),然后重新编译Apache即可。在Apache 2.0中新加入了ServerLimit指令,使得无须重编译Apache就可以加大MaxClients。下面是笔者的prefork配置段:
<IfModule prefork.c> StartServers 10 MinSpareServers 10 MaxSpareServers 15 ServerLimit 2000 MaxClients 1000 MaxRequestsPerChild 10000 </IfModule>
上述配置中,ServerLimit的最大值是20000,对于大多数站点已经足够。如果一定要再加大这个数值,对位于源代码树下server/mpm/prefork/prefork.c中以下两行做相应修改即可:
1.define DEFAULT_SERVER_LIMIT 256
2.define MAX_SERVER_LIMIT 20000
2.define MAX_SERVER_LIMIT 20000
worker的工作原理及配置
相对于prefork,worker是2.0 版中全新的支持多线程和多进程混合模型的MPM。由于使用线程来处理,钥梢源硐喽院A康那肭螅低匙试吹目∮诨诮痰姆衿鳌5牵瑆orker也使用了多进程,每个进程又生成多个线程,以获得基于进程服务器的稳定性。这种MPM的工作方式将是Apache 2.0的发展趋势。
在configure -with-mpm=worker后,进行make编译、make install安装。在缺省生成的httpd.conf中有以下配置段:
<IfModule worker.c> StartServers 2 MaxClients 150 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 25 MaxRequestsPerChild 0 </IfModule>
worker的工作原理是,由主控制进程生成“StartServers”个子进程,每个子进程中包含固定的ThreadsPerChild线程数,各个线程独立地处理请求。同样,为了不在请求到来时再生成线程,MinSpareThreads和MaxSpareThreads设置了最少和最多的空闲线程数;而MaxClients设置了所有子进程中的线程总数。如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程。
MinSpareThreads和MaxSpareThreads的最大缺省值分别是75和250。这两个参数对Apache的性能影响并不大,可以按照实际情况相应调节。
ThreadsPerChild是worker MPM中与性能相关最密切的指令。ThreadsPerChild的最大缺省值是64,如果负载较大,64也是不够的。这时要显式使用ThreadLimit指令,它的最大缺省值是20000。上述两个值位于源码树server/mpm/worker/worker.c中的以下两行:
1.define DEFAULT_THREAD_LIMIT 64
2.define MAX_THREAD_LIMIT 20000
2.define MAX_THREAD_LIMIT 20000
这两行对应着ThreadsPerChild和ThreadLimit的限制数。最好在configure之前就把64改成所希望的值。注意,不要把这两个值设得太高,超过系统的处理能力,从而因Apache不起动使系统很不稳定。
Worker模式下所能同时处理的请求总数是由子进程总数乘以ThreadsPerChild值决定的,应该大于等于MaxClients。如果负载很大,现有的子进程数不能满足时,控制进程会派生新的子进程。默认最大的子进程总数是16,加大时也需要显式声明ServerLimit(最大值是20000)。这两个值位于源码树server/mpm/worker/worker.c中的以下两行:
1.define DEFAULT_SERVER_LIMIT 16
2.define MAX_SERVER_LIMIT 20000
2.define MAX_SERVER_LIMIT 20000
需要注意的是,如果显式声明了ServerLimit,那么它乘以ThreadsPerChild的值必须大于等于MaxClients,而且MaxClients必须是ThreadsPerChild的整数倍,否则Apache将会自动调节到一个相应值(可能是个非期望值)。下面是笔者的worker配置段:
<IfModule worker.c>
StartServers 3
MaxClients 2000
ServerLimit 25
MinSpareThreads 50
MaxSpareThreads 200
ThreadLimit 200
ThreadsPerChild 100
MaxRequestsPerChild 0
</IfModule>
通过上面的叙述,可以了解到Apache 2.0中prefork和worker这两个重要MPM的工作原理,并可根据实际情况来配置Apache相关的核心参数,以获得最大的性能和稳定性。
我的配置:
<IfModule prefork.c>
StartServers 150
MinSpareServers 100
MaxSpareServers 150
ServerLimit 6193
#ServerLimit 2150
MaxClients 824
#MaxClients 600
MaxRequestsPerChild 0
</IfModule>
StartServers 150
MinSpareServers 100
MaxSpareServers 150
ServerLimit 6193
#ServerLimit 2150
MaxClients 824
#MaxClients 600
MaxRequestsPerChild 0
</IfModule>