风's profile风来西林PhotosBlogLists Tools Help

Blog


    January 21

    ubuntu 安装AMP环境的笔记 Prefork方式与fast-cgi方式

          改来改去,搜来搜去,发现GG和百度上的资料还是很凌乱,要不就是程序采集(有些采集的不伦不类的,还有错字和信息不全),可把我们这类小鸟等级的人给折腾坏了.(汗~~~~~!) 经历了无数次搜索和实际测试,归纳成一下文章,这里我只说明一些步骤,对于详细的相关说明还是不写了(如果写完的话估计我可以出书了.)

         具体步骤如下:

         系统:ubuntu 8.04 的发行版本

         AMP with Prefork(mod-php5)

          一、安装APACHE2

         # sudo  apt-get  install  apache2  apache2-mpm-prefork

         这样APACHE部分就完成,默认目录是 /var/www

         二、进行PHP的环境配置:

         # sudo  apt-get  install  php5  libapache2-mod-php5  php5-cli  php5-dev  php5-gd  php5-imagick  php5-mcrypt  php5-xmlrpc

         当然,需要更多的PHP5 extension 便可以自己补完。完成后手动启动模块:

        # sudo  a2enmod  php5

        三、MYSQL软件的安装

        # sudo  apt-get  install  mysql-server  libapache2-mod-auth-mysql  php5-mysql

        MYSQL安装完成之后一切就搞定了,不过别忘了,通过APT方式安装MYSQL在安装过程当中是必须为MYSQL的ROOT用户设置密码的。

        AMP with Worker(fast-cgi)

         如果想使用 worker 方式来跑的话必须使用fast-cgi模式,步骤如下:

        一、首先安装 apache with mpm-worker:

        # sudo  apt-get  install  apache2  apache2-mpm-worker  libapache2-mod-fcgid

       二、安装和配置PHP部分

        # sudo  apt-get  install  php5  php5-cgi  php5-cli  php5-dev  php5-gd  php5-imagick  php5-mcrypt  php5-xmlrpc

        三、MYSQL的安装配置

        # sudo  apt-get  install  mysql-server  libapache2-mod-auth-mysql  php5-mysql

         (MYSQL需要注意的部分同上,up!)

        四、配置FAST-CGI模式下的目录(我觉得这个是重点,受那些杂乱资料的影响我就失败在这块)

             在<Directory …> … </Directory> 里加入一下两句话

             AddHandler fcgid-script .php

             FCGIWrapper /usr/lib/cgi-bin/php5 .php

             并在本段的 Option 上多加一个参数 ExecCGI

         完成以上工作后,我们便可以重启apache2进行测试工作了~~!

         # sudo  /etc/init.d/apache2  force-reload

        在服务目录中我们放入写有 phpinfo(); 函数的PHP文件,才查看本LAMP环境的参数是否正确。

        附录:

         一、根据需要调整APACHE的模块

        在APACHE部分,首要的编辑就是/etc/apache2/mod-available的目录下的模块加载,你先看看自己需要哪些模块,里面有很多MOD_NAME.load和MOD_NAME.conf然后通过模块添加命令进行添加。

        模块添加的命令:

        # sudo  a2enmod  [MOD_NAME]

        举例说明:

        启用页面压缩的deflate来说,方法如下:

        # sudo  a2enmod  deflate

        然后编辑 /etc/apache2/mods-available/deflate.conf  ,改为:

        <IfModule mod_deflate.c>
            DeflateCompressionLevel  6
            AddOutputFilterByType   DEFLATE  text/html  text/plain  text/xml
            AddOutputFilter   DEFLATE  html  htm  xml  css  js
        </IfModule>

        之后重启 apache2 便可完成。

       二、关于apache2-mpm-prefork模式和FAST-CGI模式的php.ini文件位置

        apache2-mpm-prefork: /etc/php5/apache2/php.ini

        FAST-CGI:/etc/php5/cgi/php.ini

        特别是在使用eAcceleratorMMCache的时候需要特别注意!

        好了,今天暂时就先到这里了。过段时间我会陆续的把 suexec 模块userdir 模块,以及用户的磁盘配额的一些技术实现的笔记陆续公布出来,以求大家共同进步~! :-)

        

    January 11

    关于php5的一些错误处理笔记!

     1、 [error] [client 192.168.0.120] PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib/php5/20060613+lfs/pdo_mysql.so' - /usr/lib/php5/20060613+lfs/pdo_mysql.so: cannot open shared object file: No such file or directory in Unknown on line 0, referer: http://192.168.0.146/
          处理方法: 安装 php5-mysql 和 php5-snmp
          日期:2009-1-11
    November 11

    ubuntu 系统下的apache添加ssi模块

    通过apt-get install apache2 安装系统后,默认安装并没有把模块直接加载,我们需要手动添加一个软连接,便于系统自动加载该模块!执行命令如下:
    #cd /etc/apache2/mods-enabled
    #sudo ln -s /etc/apache2/mods-available/include.load

    然后再修改你的虚拟主机的配置文件

    添加 +Includes 和文件类型

    AddType text/html .shtml
    AddOutputFilter INCLUDES .shtml

    重启apache 服务

    sudo apache2ctl restart

    我们可以在页面内添加

    <!--#echo var="DATE_LOCAL" -->

    来测试一下SSI服务是否正常运行了~!大笑

    November 05

    ubuntu系统允许用户外部访问MYSQL修改

    通过管理帐号登陆MYSQL

    添加或授权一个外部访问MYSQL的帐号:

    grant all privileges on *.*(任何数据库) to 用户名@"%(此处为任何主机)" identified by "(你的密码)" with grant option;

    试用命令查看3306端口

    netstat  -an  |grep  3306

    tcp                0            0  127.0.0.1:3306                    0.0.0.0:*                              LISTEN

    从外部服务器扫描该服务器,3306也没有打开,我们修改my.cnf文件开启外部访问的权限:

    bind-address           = 127.0.0.1  #将该处的配制删除或注释掉,因为该参数是限制访问只能是本机

    忘记了UBUNTU系统中的MYSQL ROOT 密码修改方法

    (1)以系统root权限登陆

    (2)停止MYSQL服务器:

    mysqladmin shutdown

    (3)跳过授权表执行MYSQL服务器:

    mysqld_safe --skip-grant-tables --skip-networking & (注:参数--skip-grant-tables为跳过授权表;--skip-networking为不监听TCP/IP连接)

    October 28

    ubuntu 下将通过APT安装将mod模式的PHP改成fastcgi

    在Ubuntu中搭建一般的LAMP环境实在是太简单的一件事, 只需要:

    $sudo apt-get install apache2 php5 mysql-server libapache2-mod-php5

    然而, 这样搭建出来的LAMP环境, PHP是通过Apache2的mod执行的, 这也就是软件包libapache2-mod-php5的作用. 通过mod执行的PHP有速度快, 方便等诸多优势.但是在其他方面诸如用户权限分离和使用动态虚拟主机创建等,都需要使用fastcgi模式来运行PHP。

    在网上找到了一篇资料测试通过,拿出来给大家分享!具体操作入下:

    首先, 删除libapache2-mod-php5, 因为没用了.$sudo a2dismod php5

    $sudo apt-get remove libapache2-mod-php5

    安装cgi版的php(自己会支持fcgi的)和apache2的action模块

    $sudo apt-get install php5-cgi
    $sudo a2enmod actions

    新建目录, 把安装的php5-cgi扔过去

    $sudo mkdir /usr/local/php5-fcgi
    $sudo mkdir /usr/local/php5-fcgi/bin
    $sudo cp /usr/bin/php5-cgi /usr/local/php5-fcgi/bin/

    下面关键了, 总是出错的就是这了
    在你的虚拟主机配置(sites-enabled那里)文件, <VirtualHost > 之内, 其他标签之外添加这些内容:

    ScriptAlias /fcgi-bin/ "/usr/local/php5-fcgi/bin/"
    Action php-fastcgi /fcgi-bin/php5-cgi
    AddHandler php-fastcgi .php
    AddType application/x-httpd-php .php
    <Location /fcgi-bin>
    Options FollowSymLinks ExecCGI
    </Location>

    然后重启apache2, 完事.

    October 27

    修改新数据在安装时没设置密码而无法登陆的办法

    今天拿到一台安装有UBUNTU系统的服务器,MYSQL都是APT安装的,哎,老大安装机器的时候不知道怎么了,都不喜欢在MYSQL里设置密码,我哭~!然后尝试登陆,怎么也登陆不上去,各种修改MYSQL root密码的方法都用都不成,后来急得我把user表的数据库文件用编辑器打开来看。发现里面只有一个debian-sys-maint用户。当时差点没哭出来。难怪我使用安全模式登陆到 MYSQL没有发现其他的用户。

    着下可有办法了。我先把一个正常能登陆(有没有设置密码都无所谓)的MYSQL的USER表文件CP到着个机器的数据库表文件目录里,然后修改文件权限,重启服务。此时提供会报错误~!

    error: 'Access denied for user 'debian-sys-maint'@'localhost' (using password: YES)'

    不怕。数据还是能起来的。呵呵。正常登陆进去后就开始修改一下user表中的debian-sys-maint用户密码,传说因为是系统启动MYSQL的时候专用帐号,每次关闭和启动的时候密码都是新的,所以就会出现前面那个系统错误。修改了它就OK了。当前最新的密码应该在你系统的

    vi /etc/mysql/debian.cnf

    # Automatically generated for Debian scripts. DO NOT TOUCH!
    [client]
    host     = localhost
    user     = debian-sys-maint
    password = 1orZidSkUO1iQtEF    《==这个
    socket   = /var/run/mysqld/mysqld.sock
    [mysql_upgrade]
    user     = debian-sys-maint
    password = 1orZidSkUO1iQtEF  
    socket   = /var/run/mysqld/mysqld.sock
    basedir  = /usr

    执行如下MYSQL命令:

    SET PASSWORD FOR 'debian-sys-maint'@'localhost' = PASSWORD('你的密码');

    然后再重启MYSQL就发现错误没辣~~!搞定。

    后话:发现咱老大也瞒懒的~~!怒~~!

    October 23

    [Apache] mod_bw 頻寬下載限制

     

    转载:http://blog.wu-boy.com/2007/08/20/119/

    自己在站内有写一篇 [apache] mod_cband 频宽限制,不过这套好像没有真对网站用 header「[PHP] header下载档案 搭配资料库」 吐出来的下载方式做限制,只能针对单存下载的连结做限制,所以自己爬文了一下,又找到了 Bandwidth Module 这个套件,Banwidth官方网,目前出到 mod_bw v0.8 说明档

    底下是针对 FreeBSD 安装方式,所以其他安装方法就参考上面的说明档了

    cd /usr/ports/www/mod_bw/
    make install clean

    上面这样就安装好了,再来就是设定 mod_bw 了

    • BandWidthModule [On|Off]

    apaceh 预设是关闭的,所以请把他打开

    BandWidthModule on
    • ForceBandWidthModule [On|Off]

    这个设定预设情形,他不会对每个要求限制,如果你把他打开,他就会对每个要求做限制
    普通要求:AddOutputFilterByType MOD_BW text/html text/plain
    打开设定:ForceBandWidthModule On

    • BandWidth [From] [bytes/s]

    这个设定有2个参数,第一是from,第二是速度,第一你可以用整个ip位址,或者是network mask例如:192.168.0.0/24 or 192.168.0.0/255.255.255.0) or all。最后的all就是全部皆可,不限制

    BandWidth localhost 10240
    BandWidth 192.168.218.5 0

    上面针对 localhost 给 10KB的速度,然后针对 192.168.218.5 不限制速度
    在版本0.8还可以针对client端的瀏览器做限制

    • BandWidth u:[User-Agent] [bytes/s]

    你可以利用正规语法比对client端瀏览器

    BandWidth "u:^Mozilla/5(.*)" 10240
    BandWidth "u:wget" 102400

    还蛮不错的功能

    • MinBandWidth [From] [bytes/s]
    BandWidth    all 102400
    MinBandWidth all 50000

    The example above, will have a top speed of 100kb for the 1º
    client. If more clients come, it will be splitted accordingly but
    everyone will have at least 50kb (even if you have 50 clients)

    BandWidth    all 50000
    MinBandWidth all -1

    上面这个例子是保证client端下载速度保证 50KB/s

    • LargeFileLimit [Type] [Minimum Size] [bytes/s]

    这个专门是用来限制大型档案,譬如说影音档 avi wmv 之类的 还蛮好用的喔

    LargeFileLimit .avi 500 10240

    上面是说如果 avi档案超过500KB 就限制速度在 10KB

    • BandWidthPacket

    这个不用理他,不要随便调整他

    • BandWidthError [Error]

    这是错误讯息导向,比如说超过限制,你可以写个html档然后导向那边

    ErrorDocument 510 /errors/maxconexceeded.html
    BandWidthError 510
    • MaxConnection [From] [Max]

    限制连线数目,这个还蛮好用的

    限制所有连线速度无限,但是只能有20条连线

    BandWidth all 0
    MaxConnection all 20

    限制无限制ip速度无限,连线数20,然后网域192.168.0.0/24的速度 10KB,连线数目5

    BandWidth all 0
    BandWidth 192.168.0.0/24 10240
    MaxConnection all 20
    MaxConnection 192.168.0.0/24 5

    然后在举一些官方的例子

    Limit every user to a max of 10Kb/s on a vhost :

    <Virtualhost *>
    BandwidthModule On
    ForceBandWidthModule On
    Bandwidth all 10240
    MinBandwidth all -1
    Servername www.example.com
    </Virtualhost>

    Limit al internal users (lan) to 1000 kb/s with a minimum of 50kb/s , and
    files greater than 500kb to 50kb/s.

    <Virtualhost *>
    BandwidthModule On
    ForceBandWidthModule On
    Bandwidth all 1024000
    MinBandwidth all 50000
    LargeFileLimit * 500 50000
    Servername www.example.com
    </Virtualhost>

    限制 avi 跟 mpg 速度 20kb/s.

    <Virtualhost *>
    BandwidthModule On
    ForceBandWidthModule On
    LargeFileLimit .avi 1 20000
    LargeFileLimit .mpg 1 20000
    Servername www.example.com
    </Virtualhost>

    Using it the "right" way, with output filter by mime type (for text)
    to 5kb/s:

    <Virtualhost *>
    BandwidthModule On
    AddOutputFilterByType MOD_BW text/html text/plain
    Bandwidth all 5000
    Servername www.example.com
    </Virtualhost>

    FTP目录和PHP服务目录分离,但整合在一个域名之下

    FTP目录和PHP服务目录分离,但整合在一个域名之下

    要求:

    一、FTP和WEBPHP程序分离不同的目录,且必须在同一个域名之下
    二、FTP用户上传的PHP程序不能被执行。
    三、大众用户下载FTP内的软件通过WEB的HTTP协议下载,下载需要进行下载限速。
    四、防止外网盗链和讯雷盗链

    软件列表:

    1、apache2
    2、MYSQL5
    3、PHP5
    4、PROFTPD-MYSQL(通过MYSQL限制进行磁盘配额)
    5、UBUNTU 8

    (软件安装的步骤我不在此进行说明,在我的BLOG其他日志中有详细的步骤,我只针对以上的一些特定软件和要求解决方法进行说明)

    具体步骤入下:

    一、FTP和WEBPHP程序分离不同的目录,且必须在同一个域名之下

    网站的主目录为 /var/www/www.site.com

    FTP的主目录为 /var/ftp/[用户名]/文件目录

    在www.site.com虚拟主机的配置文件中使用

    Alias "soft" "/var/ftp"

    二、FTP用户上传的PHP程序不能被执行。

    然后增加一下代码用于限制PHP解释,防止FTP用户上传恶意PHP程序并执行 “php_admin_flag engine off” 代码如下:

    <Directory "/var/ftp/">
        php_admin_flag engine off
        Options -Indexes
        AllowOverride ALL
        Order allow,deny
        Allow from all
    </Directory>

    三、大众用户下载FTP内的软件通过WEB的HTTP协议下载,下载需要进行下载限速。

    对于APACHE2的用户访问限制我在这里使用的是mod_bw模块,通过APXS2进行安装。首先要确定该APACHE2服务内是否安装有MOD_BW模块。(有没有装自己心理明白,呵呵!)先对apxs2进行检查,执行:

    $ apxs2

    如果出现提示是未知的命令说明你还没有安装。

    接下来便开始安装apxs2,先检查自己的APT是否是最新的

    $ apt-get update

    安装apxs2

    $ apt-get install apache2-prefork-dev

    安装gcc

    $ apt-get install gcc

    去mod_bw的官网下在最新的版本,解压后修改mod_bw.c内的代码:

    将原本的:

    /* Compatibility for ARP < 1 */
    #if (APR_MAJOR_VERSION < 1)
    #define apr_atomic_inc32 apr_atomic_inc
    #define apr_atomic_dec32 apr_atomic_dec
    #define apr_atomic_add32 apr_atomic_add
    #define apr_atomic_cas32 apr_atomic_cas
    #define apr_atomic_set32 apr_atomic_set
    #endif

    改成:

    /* Compatibility for ARP < 1 */
    /*
    #if (APR_MAJOR_VERSION < 1)
    #define apr_atomic_inc32 apr_atomic_inc
    #define apr_atomic_dec32 apr_atomic_dec
    #define apr_atomic_add32 apr_atomic_add
    #define apr_atomic_cas32 apr_atomic_cas
    #define apr_atomic_set32 apr_atomic_set
    #endif
    */

    执行模组安装

    $ apxs2 -i -a -c mod_bw.c

    安装末尾提示如下信息:

    ----------------------------------------------------------------------
    Libraries have been installed in:
    /usr/lib/apache2/modules

    If you ever happen to want to link against installed libraries
    in a given directory, LIBDIR, you must either use libtool, and
    specify the full pathname of the library, or use the `-LLIBDIR'
    flag during linking and do at least one of the following:
    - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
    during execution
    - add LIBDIR to the `LD_RUN_PATH' environment variable
    during linking
    - use the `-Wl,--rpath -Wl,LIBDIR' linker flag
    - have your system administrator add LIBDIR to `/etc/ld.so.conf'
    See any operating system documentation about shared libraries for
    more information, such as the ld(1) and ld.so(8) manual pages.
    ----------------------------------------------------------------------
    chmod 644 /usr/lib/apache2/modules/mod_bw.so
    [activating module `bw' in /etc/apache2/httpd.conf]

    这时就会安装到你的Apache的模组里,并且http.conf也已经自动加上了: LoadModule bw_module modules/mod_bw.so

    则表明安装成功!

    建立mod_bandwidth工作目录
    root# mkdir -p /tmp/apachebw/link
    root# mkdir -p /tmp/apachebw/master
    root# chown -R nobody:nobody /tmp/apachebw
    root# chmod -R 755 /tmp/apachebw

    在<Directory "/var/ftp/">处添加如下信息,可根据自己的需要进行修改

    # Limit BW usage
    BandWidthModule On
    ForceBandWidthModule On
    #開放20KB对外使用
    BandWidth all 51200
    #每Connection最小带宽为50K
    MinBandwidth all 51200
    #大于50M的文件传输速率按50Kbytes/sec
    #LargeFileLimit 51200 51200
    #最大同时连接数量
    #MaxConnection 300


    把Apache服务器重新启动就可以实现对带宽的限制了。

    四、防止外网盗链和讯雷盗链

    在对于盗链方面还没有比较好的解决思路,基本上都是通过PHP的HEADER跳转前进行referer的检查,和使用rewrite的效验,通过浏览器访问的话盗链基本没问题,但是如果将最终的URL拷贝到下载软件上,下载软件直接跳过任何效验进行下载了。

    指令名称 : chmod

    使用权限 : 所有使用者
    使用方式 : chmod [-cfvR] [--help] [--version] mode file...
    说明 : Linux/Unix 的档案调用权限分为三级 : 档案拥有者、群组、其他。利用 chmod 可以藉以控制档案如何被他人所调用。
    参数 :
    mode : 权限设定字串,格式如下 : [ugoa...][[+-=][rwxX]...][,...],其中
    u 表示该档案的拥有者,g 表示与该档案的拥有者属于同一个群体(group)者,o 表示其他以外的人,a 表示这三者皆是。
    + 表示增加权限、- 表示取消权限、= 表示唯一设定权限。
    r 表示可读取,w 表示可写入,x 表示可执行,X 表示只有当该档案是个子目录或者该档案已经被设定过为可执行。
    -c : 若该档案权限确实已经更改,才显示其更改动作
    -f : 若该档案权限无法被更改也不要显示错误讯息
    -v : 显示权限变更的详细资料
    -R : 对目前目录下的所有档案与子目录进行相同的权限变更(即以递回的方式逐个变更)
    --help : 显示辅助说明
    --version : 显示版本
    范例 :将档案 file1.txt 设为所有人皆可读取 :


    chmod ugo+r file1.txt


    将档案 file1.txt 设为所有人皆可读取 :


    chmod a+r file1.txt


    将档案 file1.txt 与 file2.txt 设为该档案拥有者,与其所属同一个群体者可写入,但其他以外的人则不可写入 :


    chmod ug+w,o-w file1.txt file2.txt


    将 ex1.py 设定为只有该档案拥有者可以执行 :


    chmod u+x ex1.py


    将目前目录下的所有档案与子目录皆设为任何人可读取 :


    chmod -R a+r *


    此外chmod也可以用数字来表示权限如 chmod 777 file


    语法为:chmod abc file


    其中a,b,c各为一个数字,分别表示User、Group、及Other的权限。
    r=4,w=2,x=1

    若要rwx属性则4+2+1=7;

    若要rw-属性则4+2=6;

    若要r-x属性则4+1=7。

    范例:


    chmod a=rwx file



    chmod 777 file


    效果相同


    chmod ug=rwx,o=x file



    chmod 771 file


    效果相同


    若用chmod 4755 filename可使此程序具有root的权限

    October 19

    使用Python在linux环境下生成网站的sitmap!

    什么是sitemap?简单的说,就是一个xml文件,定义了你网站“主要栏目”的结构,以方便搜索引擎更好的建立索引和抓取文件。是对一些从其他页面不怎么链接得到的页面尤其有用,更详细的信息可以查阅Wikipedia上的说明

    Google是支持sitemap的,Google帮助中的How do I create a Sitemap file?一文列举了一些生成sitemap的方式和工具,我采取的是第一种——sitemap protocol方式,详细说明在这里,英文好的朋友可以直接去啃,不用看我在下面罗嗦了。

    第一步,准备工作

    由于Google Sitemap Generator是使用python语言编写的,所以需要python 2.2以上的版本支持,其余的要求如要有文件的访问权等等不再详述。由于我的操作系统是Ubuntu(推荐),所以python支持也没问题。

    http://www.sourceforge.net/project/showfiles.php?group_id=137793&package_id=153422下载Google Sitemap Generator的程序文件,在本机建一个目录把它解压缩。

    第二步,创建配置文件

    把刚才解压缩得到的example_config.xml文件另存为config.xml,并编辑之:

    <site
    base_url=”http://www.daemon.com/”
    store_into=”/var/www/docroot/sitemap.xml.gz”
    verbose=”1″
    >

    其中base_url是网站地址,store_into是sitemap文件的地址,最好使用绝对路径,于是上面的内容修改为:

    <site
    base_url=”http://www.daemon.com/”
    store_into=”/var/www/sitemap.xml”
    verbose=”1″
    >

    接下来修改** MODIFY or DELETE **开头的sitemap生成方式定义部分,要删除掉不打算使用的生成方式,按照xml语法标签来分,生成方式有以下几种:

    • url,网页地址,附加定义为最后修改时间,更新周期,优先级,个人认为这种方式比较麻烦。
    • urllist,通过一个包含网页地址列表的文件,可以定义文件优先级,个人认为这种方式还不如直接使用urllist文件省事。
    • directory,文件地址,附加定义为文件、对应网址、默认索引页,个人认为这种方式比较适合我们,因为在本机一般都会有一套比较完整的网站文件,用他们来生成sitemap再合适不过了。
    • accesslog,网站日志文件,有必要么?
    • sitemap,sitemap节点文件,主要用于把多个分散的sitemap文件集合起来。

    在这里我们删除掉其他的方式,只保留directory方式,并对其进行修改,结果如下:

    <directory
    path=”你的网站物理路径” 例如:/var/www/www.daemon.com/
    url=”http://www.daemon.com/”
    default_file=”index.html” *默认文件*
    />
    <directory
    path=”你的网站物理路径” 例如:/var/www/www.daemon.com/channel/
    url=”http://www.daemon.com/channel/” *你的子栏目目录,如果子栏目有独立的目录*
    default_file=”index.html” *默认文件*
    />

    注意一般简单的网站只要有一个directory就可以了,但也可以有多个directory段,仅当你的网站是用子目录来划分栏目,也就是对应到本机不一定放在一个目录下调试的情况下才建议使用。可以用default_file来定义首页文件。

    接下来修改FILTERS段,索引文件过滤部分。过滤规则是自上而下匹配的,匹配动作action有两种drop和pass,drop明确不索引文 件,pass则是索引文件(但也有可能被后面的规则排除),匹配规则type可以是wildcard或者regexp,wildcard是使用通配符* 和?来匹配文件,regexp自然就是正则表达式了。注意默认的匹配动作是drop不索引文件,所以要想简单的索引所有文件,这一段留空就可以了。

    <filter action=”drop” type=”wildcard” pattern=”*/cert/*” />

    这里我只简单的屏蔽掉信息产业部备案文件保存的那个目录,注意pattern是要和完整的网址进行匹配,略微不同于apache conf文件中的rewrite规则写法。

    第三步,运行Google Sitemap Generator

     python sitemap_gen.py --config=</var/www/www.daemon.com/config.xml>

    运行成功后系统会出现一下内容:

    Reading configuration file: /var/www/www.daemon.com/config.xml
    The Sitemap type is WEB Sitemap.
    Walking DIRECTORY "/var/www/www.daemon.com/"
    Walking DIRECTORY "/var/www/www.daemon.com/html/"
    Walking DIRECTORY "/var/www/www.daemon.com/html/video/"
    Walking DIRECTORY "/var/www/www.daemon.com/html/films/"
    Sorting and normalizing collected URLs.
    Writing Sitemap file "sitemap.xml" with 10953 URLs
    Notifying search engines.
    Notifying: www.google.com
    Count of file extensions on URLs:
          1 (no extension)
          1680 .gif
          3944 .html
          3475 .jpg
          10 .php
          2 .py
          1 .swf
          1738 .txt
          2 .xml
          100 /
          Number of errors: 0
          Number of warnings: 0

    最后,登录Google Webmaster Tools提交你的sitemap文件即可。

    October 18

    Linux下磁盘分区管理

        在Linux下对IDE的设备是以hd命名的,第一个ide设备是hda,第二个是hdb,依此类推。SCSI接口设备是用sd命名的,第一个设备是 sda,第二个是sdb,依此类推。分区是用设备名称加数字命名的。例如hda1代表hda这个硬盘设备上的第一个分区,hda2代表hda这个硬盘设备上的第二个分区。linux下对分区的编号,第一个主分区为1,其次为2,3,最大为4,扩展盘上的逻辑分区从5开始。

        新添加的硬盘可以在/dev下找到,下面以新加的一块SCSI硬盘/dev/sdb为例说明。首先用fdisk进行分区。

    #fdisk /dev/sdb 

        进入fdisk模式。可以用m命令来看fdisk命令的内部命令;n命令创建一个新分区;d命令删除一个存在的分区;p命令显示分区列表;t命令修改分区的类型ID号;l命令显示分区ID号的列表;a命令指定启动分区;w命令是将对分区表的修改存盘让它发生作用。

    Command (m for help):p  //查看新硬盘的分区
    Command (m for help):n  //创建新分区

    Command action
       e   extended   //输入e为创建扩展分区
       p   primary partition (1-4)   //输入p为创建主分区,这里我们选择p
    Partion number(1-4):1  //第一个扩展分区,按你需求可以最多分4个主分区
    First Cylinder(1-1014,default 1):  1  //第一个主分区起始的磁盘块数
    Last cylindet or +siza or +sizeM or +sizeK: +1024MB  //可以是以MB为单位的数字

        这样我们就创建完一个分区,如果要创建更多分区可以照上面的步骤继续创建。如果要创建扩展分区,就按n,e。扩展分区本身没有办法使用,必须要在扩展分区内再建逻辑分区,操作是n,l。经过多步操作,硬盘被划分成如下分区状况:

       Device Boot      Start         End      Blocks   Id  System
    /dev/sdb1               1         100      102384   83  Linux
    /dev/sdb2             101         200      102400   83  Linux
    /dev/sdb3             201         307      109568    5  Extended
    /dev/sdb5             201         260       61424   83  Linux
    /dev/sdb6             261         307       48112   83  Linux

        其中sdb1,sdb2都是主分区,sdb3是扩展分区,在扩展分区中建了两个逻辑分区,分别是sdb5和sdb6。创建完后用w保存分区。 

    Command (m for help): w
    The partition table has been altered!

    Calling ioctl() to re-read partition table.
    Syncing disks.

        这样就分区完,我们还要进行格式化:

    mkfs.ext3 /dev/sdb1

        或者

    #mkfs -t ext3 -c /dev/sdb1  //如果有多个分区,则分区修改为sdb2这样

        扩展分区不能直接格式化,需要单独格式化各个逻辑分区。格式化完后我们需要进行挂载分区。
    #mkdir /var/www //创建/www目录,我们将把新的分区挂到www下
    #mount /dev/sdb1 /var/www  //将/dev/sdb1挂载到/var/www

    # df  //用df命令进行查看
    Filesystem           1K-blocks      Used Available Use% Mounted on
    /dev/sda2              3771316   1388956   2190788  39% /
    /dev/sda1               101089      9463     86407  10% /boot
    none                     62988         0     62988   0% /dev/shm
    /dev/sdb1               485906      8239    452580   2% /var/www  //看到了,这就是我们刚才新挂载的分区

        要挂载其他分区操作同上。到这里我们工作已接近尾声了,不过我们如果这样就结束的话,我们每次重新启动服务器后都要进行手工挂载,这样很麻烦,我们需要修改/etc/fstab文件来进行自动挂载。

    vi /etc/fstab

        添加

    /dev/sdb1   /var/www   ext3    defaults  1 1

    附分区表/etc/fstab格式简介:

        linux在引导过程中用该表来按不同的方式装载分区和目录。每个文件系统有几个相干的参数,这些参数确定文件系统如何读取、文件系统有哪些相关用户权限等。
        该表一般包含6个字段。
       <file system>(有的系统用label表示) 要装载的分区(如/dev/hda2)和文件系统(如/usr)
       <dir> (或者mount point等) 要装载的分区和文件系统所在目录
       <type>(或format等) 文件系统格式类型,如ext3,vfat
       <options>(mount options等) 其值为defaults时,即默认选项,包括参数rw(读写)、suid(SUID权限)、exec(二进制可执行文件)、auto(系统起动时自动装载)、nouser(只有根用户可以装载,相反为user)、async(数据异步读写)),其它的参数还有umask,unhide(hide), iocharset(语言环境)等,当然你可以自己指定各个值。
       <dump>(dump value) dump(英文意为倾倒垃圾)时是否需要BACKUP的标志位,其内定值是0。1表示文件系统自动写入磁盘。
       <pass>(Filesystem Check Order) 设定此filesystem是否要在开机时做check的动作,除了root的filesystem其必要的check为1之外,其它皆可视需要设定,内定值是0。
        例子:如果你有windows分区(fat32)在/dev/hda1处,你想在系统启动时就自动挂载该分区,并且挂载过来之后一般用户可读可写,并且可以显示中文。则在fstab中添加:
        /dev/hda1  /mnt/c       vfat umask=000,iocharset=gb2312 0 0

    October 14

    ubuntu 中proftpd+mysql+虚拟用户+匿名用户+磁盘限额的配置

    安装mysql和phpmyadmin,其中phpmyadmin不是必需的

    # apt-get install mysql-server mysql-client libmysqlclient15-dev phpmyadmin apache2

    为mysql设置root密码

    # mysqladmin -u root password yourrootsqlpassword

    如果需要其他人访问本机的mysql,同样需要设置密码

    # mysqladmin -h server1.example.com -u root password yourrootsqlpassword

    安装带mysql支持的proftpd,注意选择proftpd工作在standalone模式

    # apt-get install proftpd-mysql

    建立虚拟用户组,这个是为了把proftpd用户虚拟到本机的一个用户上。注意下面的2001修改为自定义的。

    # groupadd -g 2001 ftpgroup
    # useradd -u 2001 -s /bin/false -d /bin/null -c "proftpd user" -g ftpgroup ftpuser

    建立proftpd使用的mysql数据库ftp,并创建数据表。

    mysql> create database ftp;

    为proftpd访问数据创建的帐号

    mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON ftp.* TO 'proftpd'@'localhost' IDENTIFIED BY 'password';
    mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON ftp.* TO 'proftpd'@'localhost.localdomain' IDENTIFIED BY 'password';

    创建ftpgroup表

    CREATE TABLE ftpgroup(
          groupname varchar(16) NOT NULL default '',
          gid smallint(6) NOT NULL default '5500',
          members varchar(16) NOT NULL default '',
          KEY groupname (groupname)
    ) TYPE=MyISAM;

    CREATE TABLE ftpquotalimits (
          name varchar(30) default NULL,
          quota_type enum('user','group','class','all') NOT NULL default 'user',
          per_session enum('false','true') NOT NULL default 'false',
          limit_type enum('soft','hard') NOT NULL default 'soft',
          bytes_in_avail int(10) unsigned NOT NULL default '0',
          bytes_out_avail int(10) unsigned NOT NULL default '0',
          bytes_xfer_avail int(10) unsigned NOT NULL default '0',
          files_in_avail int(10) unsigned NOT NULL default '0',
          files_out_avail int(10) unsigned NOT NULL default '0',
          files_xfer_avail int(10) unsigned NOT NULL default '0'
    ) TYPE=MyISAM;


    CREATE TABLE ftpquotatallies (
          name varchar(30) NOT NULL default '',
          quota_type enum('user','group','class','all') NOT NULL default 'user',
          bytes_in_used int(10) unsigned NOT NULL default '0',
          bytes_out_used int(10) unsigned NOT NULL default '0',
          bytes_xfer_used int(10) unsigned NOT NULL default '0',
          files_in_used int(10) unsigned NOT NULL default '0',
          files_out_used int(10) unsigned NOT NULL default '0',
          files_xfer_used int(10) unsigned NOT NULL default '0'
    ) TYPE=MyISAM;

    CREATE TABLE ftpuser (
          id int(10) unsigned NOT NULL auto_increment,
          userid varchar(32) NOT NULL default '',
          passwd varchar(32) NOT NULL default '',
          uid smallint(6) NOT NULL default '5500',
          gid smallint(6) NOT NULL default '5500',
          homedir varchar(255) NOT NULL default '',
          shell varchar(16) NOT NULL default '/sbin/nologin',
          count int(11) NOT NULL default '0',
          accessed datetime NOT NULL default '0000-00-00 00:00:00',
          modified datetime NOT NULL default '0000-00-00 00:00:00',
          PRIMARY KEY (id),
          UNIQUE KEY userid (userid)
    ) TYPE=MyISAM;

     

    修改/etc/proftpd/proftpd.conf

    在<IfModule mod_sql.c>中增加以下代码:

    # The passwords in MySQL are encrypted using CRYPT
    SQLAuthTypes            Plaintext Crypt
    SQLAuthenticate         users groups

    # used to connect to the database
    # databasename@host database_user user_password
    SQLConnectInfo  ftp@localhost proftpd password

    # Here we tell ProFTPd the names of the database columns in the "usertable"
    # we want it to interact with. Match the names with those in the db
    SQLUserInfo     ftpuser userid passwd uid gid homedir shell

    # Here we tell ProFTPd the names of the database columns in the "grouptable"
    # we want it to interact with. Again the names match with those in the db
    SQLGroupInfo    ftpgroup groupname gid members

    # set min UID and GID - otherwise these are 999 each
    SQLMinID        500

    # create a user's home directory on demand if it doesn't exist
    SQLHomedirOnDemand on

    # Update count every time user logs in
    SQLLog PASS updatecount
    SQLNamedQuery updatecount UPDATE "count=count+1, accessed=now() WHERE userid='%u'" ftpuser

    # Update modified everytime user uploads or deletes a file
    SQLLog  STOR,DELE modified
    SQLNamedQuery modified UPDATE "modified=now() WHERE userid='%u'" ftpuser

     

    在<IfModule mod_quotatab.c>中增加一下代码:

    # User quotas
    # ===========
    QuotaEngine on
    QuotaDirectoryTally on
    QuotaDisplayUnits Mb
    QuotaShowQuotas on

    SQLNamedQuery get-quota-limit SELECT "name, quota_type, per_session, limit_type, bytes_in_avail, bytes_out_avail, bytes_xfer_avail, files_in_avail, files_out_avail, files_xfer_avail FROM ftpquotalimits WHERE name = '%{0}' AND quota_type = '%{1}'"

    SQLNamedQuery get-quota-tally SELECT "name, quota_type, bytes_in_used, bytes_out_used, bytes_xfer_used, files_in_used, files_out_used, files_xfer_used FROM ftpquotatallies WHERE name = '%{0}' AND quota_type = '%{1}'"

    SQLNamedQuery update-quota-tally UPDATE "bytes_in_used = bytes_in_used + %{0}, bytes_out_used = bytes_out_used + %{1}, bytes_xfer_used = bytes_xfer_used + %{2}, files_in_used = files_in_used + %{3}, files_out_used = files_out_used + %{4}, files_xfer_used = files_xfer_used + %{5} WHERE name = '%{6}' AND quota_type = '%{7}'" ftpquotatallies

    SQLNamedQuery insert-quota-tally INSERT "%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}" ftpquotatallies

    QuotaLimitTable sql:/get-quota-limit
    QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally

    RootLogin off
    RequireValidShell off

    分别增加日志

    QuotaLog "/var/log/proftpd.quota.log"

    SQLLogFile /var/log/proftpd.sql.log

    录入测试用户数据

    INSERT INTO `ftpgroup` (`groupname`, `gid`, `members`) VALUES ('ftpgroup', 2003, 'ftpuser');

    INSERT INTO `ftpquotalimits` (`name`, `quota_type`, `per_session`, `limit_type`, `bytes_in_avail`, `bytes_out_avail`, `bytes_xfer_avail`, `files_in_avail`, `files_out_avail`, `files_xfer_avail`) VALUES ('test', 'user', 'true', 'hard', 15728640, 0, 0, 0, 0, 0);

    INSERT INTO `ftpuser` (`id`, `userid`, `passwd`, `uid`, `gid`, `homedir`, `shell`, `count`, `accessed`, `modified`) VALUES(1, 'test', 'test123', 2001, 2001, '/home/www.example.com', '/sbin/nologin', 0, '', '');

    注意:如果的你的proftpd版本大于1.3.0的话 SQLHomedirOnDemand 需要改用 CreateHome来代替!

    name: - 用户帐号
    quota type: - user, group, class, all (we use user)
    per_session: - true or false (we use true)
    limit_type: - 硬限制 or 软限制 (我们一般用硬限制)
    bytes_in_avail: - 允许上传的字节数
    bytes_out_avail: - 允许下载的字节数
    bytes_xfer_avail: - 允许传输的字节数(包括上传/下载)
    files_in_avail: - 允许上传的文件数
    files_out_avail: - 允许下载的文件数
    files_xfer_avail: - 允许传输的文件数(包括上传/下载)

    debian 软件的安装与卸载

    一基本配置

    1. /etc/apt/sources.list文件的基本格式:

    deb http://site.http.org/debian distribution section1 section2 section3
    deb-src http://site.http.org/debian distribution section1 section2

    section3

    deb 二进制程序包 deb-src 原代码程序包
    例如:

    deb http://http.us.debian.org/debian stable main contrib non-free
    deb-src http://non-us.debian.org/debian-non-US stable non-US

    deb http://non-us.debian.org/debian-non-US stable/non-US main contrib

    non-free
    deb-src http://http.us.debian.org/debian stable main contrib non-free

    apt 会忽略以"#"开头的行

    注意: 修改/etc/apt/sources.list后,应及时更新数据库列表

    2.制作本地apt

    # mkdir /root/debs
    将自己收集的.deb包考入/root/debs目录
    # dpkg-scanpackages debs| gzip > debs/Packages.gz
    在/etc/apt/sources.listdeb 加入:
    file:/root debs/

    3.寻找速度最快的下载镜相:netselect, netselect-apt

    安装netselect软件包
    # apt-get install netselect
    测试我使用的镜像
    # netselect security.debian.org ftp.us.debian.orgftp.jp.debian.org non-

    us.debian.org people.debian.org gluck.debian.org
    520 ftp.jp.debian.org
    #
    看到了我所使用的镜像中 ftp.jp.debian.org速度最快 得分为520 (得分越低越好)
    你可以在这里查找debian的镜像列表

    http://www.debian.org/mirror/mirrors_full
    你也可以用netselect-apt下载列表
    # ls sources.list
    ls: sources.list: File or directory not found
    # netselect-apt stable
    (...)
    # ls -l sources.list
    sources.list
    #
    前提是你已经安装并运行了'wget'包

    4.把CD-ROM加入到你的/etc/apt/sources.list文件

    如果使用apt自动从CD-ROM上安装软件或升级系统,可以把它加

    入/etc/apt/sources.list文件
    # apt-cdrom add

    注: CD-ROM必须在/etc/fstab文件中已正确配置

    二、管理包

    1.apt系统使用一个数据库列表来记录系统已经安装了哪些软件,哪些没有安装,哪

    些软件可以通过apt系统自动安装 apt-get通过分析这个数据库来决定如何安装软件

    ,
    应该经常运行#apt-get update来更新此数据库

    2.安装软件包
    # apt-get install packagename
    apt-get的参数
    -h This help text.
    -d Download only - do NOT install or unpack archives
    -f Attempt to continue if the integrity check fails
    -s No-act. Perform ordering simulation
    -y Assume Yes to all queries and do not prompt
    -u Show a list of upgraded packages as well

    软件包会被下载到/var/cache/apt/archives 稍后进行安装
    如果一个软件包坏了,或者你只是想重新安装一个软件的最新版本 ,可以使用--

    reinstall参数,如
    # apt-get --reinstall install gdm
    在安装软件时,可以用apt-get install package/distribution或apt-get install

    package=version来指定软件的安装版本,如
    # apt-get install nautilus/unstable

    3.移除软件包
    apt-get remove package
    # apt-get remove gnome-panel
    这样就会移除gnome-panel以及对gnome-panel有依赖性的软件包,无法使用apt系统

    仅仅移除此软件,而保留对它有依赖性的软件包。
    apt-get remove package并不能移除这些软件的配置文件
    # apt-get --purge remove gnome-panel(这个很常用,注意前面是两横哟!)
    就可以一块把他的配置文件移除

    4.升级软件包
    apt-get upgrade

    5.升级到一个新的版本
    # apt-get -u dist-upgrade

    6.移除无用的软件包
    当安装软件时,软件包会被先下载到/var/cache/apt/archives/目录下,然后安装

    。这样这个目录所占空间会越来越大,幸运的是apt提供了相应的管理工具
    apt-get clean删除/var/cache/apt/archives/ 和

    /var/cache/apt/archives/partial/目录下所有包(锁定的除外)。
    apt-get autoclean仅删除不再能被下载的包

    7.
    8.如何维持一个混合的系统
    鉴于testing版unstable版本比稳定,又比stable版本要新 ,很多人使用testing,可

    是有些人想运行某个软件的最新版,却又不愿把这个系统升级为unstable,即想使用

    一个混合的系统,那么可以这样做:
    在 /etc/apt/apt.conf 加入:
    APT::Default-Release "testing";
    当要安装unstable软件时 加 -t 参数:
    # apt-get -t unstable install packagename
    注:不要忘记在/etc/apt/sources.list中加入相应的源

    9.从一个特定的debian版本升级软
    # apt-get install `apt-show-versions -u -b | grep unstable`件

    10.如何在软件升级时避免特定软件不会被升级
    如果你使用的bebian版本在2.2以上,仅仅需要修改/etc/apt/preferences 文件
    格式非常简单:
    Package: Pin: Priority:

    例如我要保持gaim的0.58版本 只需加上:
    Package: gaim
    Pin: version 0.58*
    统配符 * 指锁定以0.58开头的所有版本 这就是说即使存在0.58-1 或类似 也不会

    被安装
    Priority(优先级)是可选项 默认 989
    <0 此软件永不会被安装
    0~100 软件不被安装,不是有效的版本
    >100 此软件会被安装 即 如果有更新版本,软件会被升级
    100~1000 软件不会被降级安装,例如:我安装的gaim 0.59 , 锁定gaim 0.58 ,优先

    级为999
    那么0.58就不会被安装 ,如果要降级安装 则优先级许大于 1000

    获取软件信息

    1.搜寻软件名
    # apt-cache search gaim
    软件信息
    # apt-cache show gaim
    如果已经安装,并且又有了新版本,那么都会显示,安装版本在后
    获取更多信息
    # apt-cache showpkg gaim
    查询软件的依赖性
    # apt-cache depends gaim

    2.用dpkg查询软件名
    根据某一个文件查询软件名
    # dpkg -S stdio.h

    3.询问式安装
    # auto-apt run command

    4.查询文件的归属
    # apt-file search filename
    就象dpkg -S 但可以查询,但可以查未安装软件包
    也可以查询一个包所含文件
    # apt-file list packagename
    它会用到数据库所以要及时更新
    # apt-file update

    程序源文件

    1.下载程序源码
    # apt-get source packagename
    这样就会下载三个文件 a .orig.tar.gz, a .dsc 和 a .diff.gz
    下载后自动打包
    # apt-get -b source packagename

    2.编译软件
    # apt-get build-dep gmc
    下载所编译包的依赖程序

    October 13

    DEBIAN的CN99源

    顶!我常用的。打开 /etc/apt/sources.list


    deb http://ubuntu.cn99.com/ubuntu/ hardy main restricted universe multiverse
    deb http://ubuntu.cn99.com/ubuntu/ hardy-security main restricted universe multiverse
    deb http://ubuntu.cn99.com/ubuntu/ hardy-updates main restricted universe multiverse
    deb http://ubuntu.cn99.com/ubuntu/ hardy-proposed main restricted universe multiverse
    deb http://ubuntu.cn99.com/ubuntu/ hardy-backports main restricted universe multiverse
    deb-src http://ubuntu.cn99.com/ubuntu/ hardy main restricted universe multiverse
    deb-src http://ubuntu.cn99.com/ubuntu/ hardy-security main restricted universe multiverse
    deb-src http://ubuntu.cn99.com/ubuntu/ hardy-updates main restricted universe multiverse
    deb-src http://ubuntu.cn99.com/ubuntu/ hardy-proposed main restricted universe multiverse
    deb-src http://ubuntu.cn99.com/ubuntu/ hardy-backports main restricted universe multiverse
    deb http://ubuntu.cn99.com/ubuntu-cn/ hardy main restricted universe multiverse

    然后在
    # apt-get update && apt-get upgrade

    ubuntu安装和配置SVN

    1. 安装SVN
    apt-get install subversion
    2. 建立svn仓库
    1). 建立svn目录:mkdir /home/.svn(使用隐藏目录)
    2). cd /home/.svn
    3). mkdir astar
    4). 创建仓库astar:svnadmin create /home/.svn/astar,执行完毕后astar目录有svnadmin创建的目录和文件
    5). mkdir test
    6). 创建仓库test:svnadmin create /home/.svn/test,执行完毕后test目录有svnadmin创建的目录和文件
    3. 配置和管理svn
    1). 每个仓库的配置文件在$repos/conf/下,vi svnserve.conf,配置项在[general]下:
    anon-access:匿名用户的权限,可以为read,write和none,默认值read。不允许匿名用户访问:anon-access = none
    auth-access:认证用户的权限,可以为read,write和none,默认值write。
    password-db:密码数据库的路径,去掉前边的#
    authz-db:认证规则库的路径,去掉前边的#。
    注意:这些配置项的行都要顶格,否则会报错。修改配置后需要重启svn才能生效。
    2). 配置passwd文件
    这是每个用户的密码文件,比较简单,就是“用户名=密码”,采用的是明码。如allen=111111
    3). 配置authz文件
    1. [groups] section:为了便于管理,可以将一些用户放到一个组里边,比如:owner=allen,ellen
    2. groups下边的sections表示对一个目录的认证规则,比如对根目录的认证规则的section为[/]。设置单用户的认证规则时一个用户一行,如:
    [/]
    allen=rw  #allen对根目录的权限为rw
    ellen=r   #ellen对根目录的权限为r
    如果使用group,需要在group名字前加@,如
    @owner=rw  #group owner中的用户均为rw,等价于上边的两句话
    启动时如果从/home/.svn/astar启动,/就是astar目录,用如上方式以astar目录为根设置权限。
    如果从/home/.svn/启动,每个仓库根还是自己的起始目录。可以采用如上方式设置astar的权限,也可以采用如下方式:
    [astar:/]
    @owner=rw
    设置test的权限如下:
    [test:/]
    @harry_and_sally = rw
    简言之,每个仓库的根目录(/)就是自己的起始目录;[repos:/]这种方式只适用于多仓库的情况;[/]适合于单仓库和单仓库的方式。
    3. 不能跨越仓库设置权限。
    4. 启动和停止svn
    1). 启动:
    1. 从astar目录启动,svnserve -d -r /home/.svn/astar,根目录(/)是astar,authz中规则的配置使用section[/]。访问方式为:
    svn://192.168.0.87/
    2. 从.svn目录启动,svnserve -d -r /home/.svn,根目录(/)是.svn,authz中对astar的配置使用section[astar:/] ,对test的配置使用section[test:/]。访问方式为:
    svn://192.18.0.87/astar
    svn://192.18.0.87/test
    如果需要svn自启动,把命令加入/etc/rc.local中
    2). 检查svn服务器是否已经启动(svn默认使用3690端口):netstat -an | grep 3690
    3). 停止:killall svnserve
    5. svn client

    在checkout的情况下出现类似提示:

    svn: Can't convert string from 'UTF-8' to native encoding

    解决的办法是在root权限下在任何目录下执行LANG="zh_CN.UTF-8"这真是一个不是问题的问题,可能是为了方便将语言格式改成E文造成的

    October 04

    PHP截取中文字符串方法总结 (转)

    第一部分的函数我测试了utf-8的编码没有出现问题,估计是测试不够变态,呵呵!不过经过以后的测试我会对本文章进行修改!

    第一部分
    ------------------------------------------------------------------------------------

    程序一:PHP截取中文字符串方法
    由于网站首页以及vTigerCRM里经常在截取中文字符串时出现乱码(使用substr),今天找到一个比较好的截取中文字符串方法,在此与大家共享。
    function msubstr($str, $start, $len) {
        $tmpstr = "";
        $strlen = $start + $len;
        for($i = 0; $i < $strlen; $i++) {
            if(ord(substr($str, $i, 1)) > 0xa0) {
                $tmpstr .= substr($str, $i, 2);
                $i++;
            } else
                $tmpstr .= substr($str, $i, 1);
        }
        return $tmpstr;
    }
    程序二:PHP截取UTF-8字符串,解决半字符问题
    /******************************************************************
    * PHP截取UTF-8字符串,解决半字符问题。
    * 英文、数字(半角)为1字节(8位),中文(全角)为3字节
    * @return 取出的字符串, 当$len小于等于0时, 会返回整个字符串
    * @param $str 源字符串
    * $len 左边的子串的长度
    ****************************************************************/
    function utf_substr($str,$len)
    {
    for($i=0;$i<$len;$i++)
    {
    $temp_str=substr($str,0,1);
    if(ord($temp_str) > 127)
    {
    $i++;
    if($i<$len)
    {
    $new_str[]=substr($str,0,3);
    $str=substr($str,3);
    }
    }
    else
    {
    $new_str[]=substr($str,0,1);
    $str=substr($str,1);
    }
    }
    return join($new_str);
    }
    ?>
    php utf-8 字符串截取
    <?
    function cutstr($string, $length) {
            preg_match_all("/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/", $string, $info); 
            for($i=0; $i<count($info[0]); $i++) {
                    $wordscut .= $info[0][$i];
                    $j = ord($info[0][$i]) > 127 ? $j + 2 : $j + 1;
                    if ($j > $length - 3) {
                            return $wordscut." ...";
                    }
            }
            return join('', $info[0]);
    }
    $string="242432反对感是456犯得上广泛大使馆地方7890";
    for($i=0;$i<strlen($string);$i++)
    {
    echo cutstr($string,$i)."<br>";
    }
    ?>
    截取utf-8字符串函数
    为了支持多语言,数据库里的字符串可能保存为UTF-8编码,在网站开发中可能需要用php截取字符串的一部分。为了避免出现乱码现象,编写如下的UTF-8字符串截取函数
    关于utf-8的原理请看 [url=http://www.allosoft.com/bB2/viewtopic.php?t=13][color=#0000ff]UTF-8 FAQ[/color][/url]
    UTF-8编码的字符可能由1~3个字节组成, 具体数目可以由第一个字节判断出来。(理论上可能更长,但这里假设不超过3个字节)
    第一个字节大于224的,它与它之后的2个字节一起组成一个UTF-8字符
    第一个字节大于192小于224的,它与它之后的1个字节组成一个UTF-8字符
    否则第一个字节本身就是一个英文字符(包括数字和一小部分标点符号)。
    以前为某网站设计的代码(也是现在用在首页的长度截取的函数)
    [b]Code:[/b]
    <?php // Cut_Str;
    //$sourcestr 是要处理的字符串
    //$cutlength 为截取的长度(即字数)
    function cut_str($sourcestr,$cutlength)
    {
       $returnstr='';
       $i=0;
       $n=0;
       $str_length=strlen($sourcestr);//字符串的字节数
       while (($n<$cutlength) and ($i<=$str_length))
       {
          $temp_str=substr($sourcestr,$i,1);
          $ascnum=Ord($temp_str);//得到字符串中第$i位字符的ascii码
          if ($ascnum>=224)    //如果ASCII位高与224,
          {
             $returnstr=$returnstr.substr($sourcestr,$i,3); //根据UTF-8编码规范,将3个连续的字符计为单个字符        
             $i=$i+3;            //实际Byte计为3
             $n++;            //字串长度计1
          }
          elseif ($ascnum>=192) //如果ASCII位高与192,
          {
             $returnstr=$returnstr.substr($sourcestr,$i,2); //根据UTF-8编码规范,将2个连续的字符计为单个字符
             $i=$i+2;            //实际Byte计为2
             $n++;            //字串长度计1
          }
          elseif ($ascnum>=65 && $ascnum<=90) //如果是大写字母,
          {
             $returnstr=$returnstr.substr($sourcestr,$i,1);
             $i=$i+1;            //实际的Byte数仍计1个
             $n++;            //但考虑整体美观,大写字母计成一个高位字符
          }
          else                //其他情况下,包括小写字母和半角标点符号,
          {
             $returnstr=$returnstr.substr($sourcestr,$i,1);
             $i=$i+1;            //实际的Byte数计1个
             $n=$n+0.5;        //小写字母和半角标点等与半个高位字符宽...
          }
       }
             if ($str_length>$cutlength){
              $returnstr = $returnstr . "...";//超过长度时在尾处加上省略号
          }
        return $returnstr;
    }

    ---------------------------------------------------------------------------------

    第二部分

    ----------------------------------------------------------------------------------

    后来在论坛上看到有朋友提出更新的意见,代码如下:

    [code]// 切断文字列(以上长度时用...表示)
    function cut_str($msg,$cut_size,$charset="UTF-8",$suffix="...") {
    if($cut_size<=0) return $msg;
    $i=1;$han=0;$eng=0;
    while ($i <= strlen($msg)) {
      if(ord($msg[($i-1)])>127){
       $han++;
       if($charset=="UTF-8"){
        $i=$i+3;
       }else{
        $i=$i+2;
       }
      }else{
       $eng++;
       $i=$i+1;
      }
      if(($han+$eng)==$cut_size){
       if($charset=="UTF-8"){
        $cut_size = $eng + (int)$han*3;
       }else{
        $cut_size = $eng + (int)$han*2;
       }
       break;
      }
    }
    for ($i=0;$i<$cut_size;$i++) {
      $str .=$msg[$i];
    }
    return $str.$suffix;
    }[/code]

    [code]// 截取文字段落(超出长度用后缀表示)
    // 设计思路按照排除法,排除字符段落中的英文字符
    // 再按照英文字符为1个占位符,中文为2个占位符(UTF-8的中文是3个占位符)
    // 计算出截取文字个数的占位符长度进行截取
    function cut_str($msg,$cut_size,$charset="UTF-8",$suffix="...") {
            //验证截取个数,如果是0将不截取
            if($cut_size<=0) return $msg;
            $i=1;
            $han=0;
            $eng=0;
            while ($i <= strlen($msg)) {
                    //判断是否是ASCII扩展字符
                    if(ord($msg[($i-1)])>127){
                            $han++;
                            if($charset=="UTF-8"){
                                    $str .=$msg[($i-1)].$msg[($i)].$msg[($i+1)];
                                    //如果是UTF-8跳过3个ASCII
                                    $i=$i+3;
                            }else{
                                    $str .=$msg[($i-1)].$msg[($i)];
                                    $i=$i+2;
                            }
                    }else{
                            $eng++;
                            $str .=$msg[($i-1)];
                            $i++;
                    }
                    //如果汉字和英文总和等于要截取的字符个数那么跳出循环
                    if(($han+$eng)==$cut_size){break;}
            }
            //如果汉字和英文总和等于要截取的字符个数那么不显示后缀
            $suffix = ($han+$eng)<$cut_size?"":$suffix;
            return $str.$suffix;
    }[/code]

    September 29

    用Smarty模板生成html文件

    在Smarty模板函数里面有这样一个方法:fetch("template.htm"),他和display("template.htm");最大的不同就是fetch()是把内容输出给一个变量,而display()是把内容输出给浏览器,这样我们就可以用一个变量来接收fetch()的输出,然后把他写入到文件中去.

    require_once(DIRROOT.'smarty/Smarty.class.php');
    $smarty = new Smarty();
    $smarty->template_dir = DIRROOT.'/smarty/template/';
    $smarty->compile_dir = DIRROOT.'/smarty/tempcomp/';
    $smarty->cache_dir = DIRROOT.'/smarty/caches/';
    $smarty->cache_lifetime =   600 ;
    $smarty->left_delimiter = "{-";
    $smarty->right_delimiter = "-}";
    $smarty->caching = false;
    //$smarty->caching = true;
    $html=$smarty->fetch("template.htm");
    $fp = fopen($file_name,"w+");
    if(!fwrite($fp,$html)){
       die('生成html文件失败!');
    }
    fclose($fp);

    September 28

    JavaScript框架编程

    1. Opener:获取创建本窗口的窗口的引用,不在本窗口的对象层次体系中

    只能在用window.open打开的页面中窗口中可以访问到opener属性,而对于用showModalDialog和showModalessDialog弹出的窗口则不能访问到,其opener属性引用为空。

    2. parent,top:获取的是对本窗口中对象层次元素的引用,对于用iframe或者frame的较有实际意义

    对于用window.open和showModalDialog以及showModalessDialog打开的窗口而言,返回的是本窗口对象层次的元素引用,对于这种情况,parent,top,self三者的引用相同,都是当前的窗体自身,但对于窗体中的 frame和iframe加载的页面元素来说,返回的则不相同。parent 返回的时包含该iframe的页面窗口引用,top则返回最上层的窗口引用,self当然返回的仍然是自身的引用。

    3. self,window都是获取当前页面窗口自身对象的引用

    每个页面自身代码中访问页面自身窗体可以采用self和window来访问到。

    4. 利用window参数传递和dialogArguments来获取弹出窗口的窗口引用

    为了能够在用showModalDialog和showModalessDialog弹出窗口中引用到弹出窗口的引用,我们可以在showModalDialog和showModalessDialog的第二个参数传入window,然后再弹出的页面中用 dialogArguments来获取刚才传入的window,即弹出窗口的窗口的引用。

    使用JavaScript框架
      在讲述 window 对象的时候,我们提到过,一个框架内的网页也是 window 对象,也就是说,Frame 对象也是 window 对象。用最容易理解的话说,每一个 HTML 文件占用一个 window 对象,包括定义框架的网页(“框架网页”)。在 IE 里用“<iframe>”标记在文档中插入的框架也是 window 对象,但是用“包含网页”的方法(在 HTML 中显示为“<!--webbot bot="include" ...-->”)读取的 HTML 就不占用独自的 window 对象。每一个框架都是包含它的页的 window 对象的一个子对象(不知道应该叫“属性”不该),要引用它,可以用以下几种方法之一:

    window.frames[x]
    window.frames['frameName']
    window.frameName

      其中,x 指的是该 window 对象中指定的第几个框架,与其它数组一样,x 也是从零开始的。frameName 指的是该框架的名字,跟<frame>里的“name”属性一样。
      如果使用 window.frameName 指定的 window 对象又是一个框架网页,那么引用它的框架的方法:window.frameName.subFrameName。以此类推。
      要注意的时,无论在何处,引用“window”对象所返回的,都是“当前”window 对象。如果要访问其它 window 对象,就要用到 parent 和 top 属性。parent 指的是“父级”window 对象,也就是包含当前 window 对象的框架网页;top 指的是窗口最顶端的 window 对象。
      使用框架还要密切留意你的 JavaScript 中定义的全局变量和自定义函数。它们都有它们的所属——所在的 window 对象。要引用其它框架中的全局变量或自定义函数,都要用“窗口对象.框架对象[.框架对象…].全局变量或自定义函数”这种很烦的方法。
      以上这个问题在建立连接时经常会被忽略:如果在<head>中定义了一个默认目标窗口(<base target="...">),在<a href="javascript:...">中,要知道输入的 JavaScript 语句是在默认目标窗口中运行的,必要时加一些“parent”“top”属性。
    框架编程概述
    一个HTML页面可以有一个或多个子框架,这些子框架以<iframe>来标记,用来显示一个独立的HTML页面。这里所讲的框架编程包括框架的自我控制以及框架之间的互相访问,例如从一个框架中引用另一个框架中的 JavaScript变量、调用其他框架内的函数、控制另一个框架中表单的行为等。
    框架间的互相引用
    一个页面中的所有框架以集合的形式作为window对象的属性提供,例如:window.frames就表示该页面内所有框架的集合,这和表单对象、链接对象、图片对象等是类似的,不同的是,这些集合是document的属性。因此,要引用一个子框架,可以使用如下语法:

    window.frames["frameName"];
    window.frames.frameName
    window.frames[index]

    其中,window字样也可以用self代替或省略,假设frameName为页面中第一个框架,则以下的写法是等价的:

    self.frames["frameName"]
    self.frames[0]
    frames[0]
    frameName

    每个框架都对应一个HTML页面,所以这个框架也是一个独立的浏览器窗口,它具有窗口的所有性质,所谓对框架的引用也就是对window对象的引用。有了这个window对象,就可以很方便地对其中的页面进行操作,例如使用window.document对象向页面写入数据、使用 window.location属性来改变框架内的页面等。
    下面分别介绍不同层次框架间的互相引用:
    1.父框架到子框架的引用
    知道了上述原理,从父框架引用子框架变的非常容易,即:

    window.frames["frameName"];

    这样就引用了页面内名为frameName的子框架。如果要引用子框架内的子框架,根据引用的框架实际就是window对象的性质,可以这样实现:

    window.frames["frameName"].frames["frameName2"];

    这样就引用到了二级子框架,以此类推,可以实现多层框架的引用。
    2.子框架到父框架的引用
    每个window对象都有一个parent属性,表示它的父框架。如果该框架已经是顶层框架,则window.parent还表示该框架本身。
    3.兄弟框架间的引用
    如果两个框架同为一个框架的子框架,它们称为兄弟框架,可以通过父框架来实现互相引用,例如一个页面包括2个子框架:

    <frameset rows="50%,50%">
       <frame src="1.html" />
       <frame src="2.html" />
    </frameset>

    在frame1中可以使用如下语句来引用frame2:

    self.parent.frames["frame2"];

    4.不同层次框架间的互相引用
    框架的层次是针对顶层框架而言的。当层次不同时,只要知道自己所在的层次以及另一个框架所在的层次和名字,利用框架引用的window对象性质,可以很容易地实现互相访问,例如:

    self.parent.frames["childName"].frames["targetFrameName"];

    5.对顶层框架的引用
    和parent属性类似,window对象还有一个top属性。它表示对顶层框架的引用,这可以用来判断一个框架自身是否为顶层框架,例如:

    //判断本框架是否为顶层框架
    if(self==top){
           //dosomething
    }

    改变框架的载入页面
    对框架的引用就是对window对象的引用,利用window对象的location属性,可以改变框架的导航,例如:

    window.frames[0].location="1.html";

    这就将页面中第一个框架的页面重定向到1.html,利用这个性质,甚至可以使用一条链接来更新多个框架。

    <frameset rows="50%,50%">
       <frame src="1.html" />
       <frame src="2.html" />
    </frameset>
    <!--somecode-->
    <a href="frame1.location='3.html;frame2.location='4.html'" >link</a>
    <!--somecode-->

    引用其他框架内的JavaScript变量和函数
    在介绍引用其他框架内JavaScript变量和函数的技术之前,先来看以下代码:

    <script language="JavaScript" type="text/javascript">
    <!--
    function hello(){
       alert("hello,ajax!");
    }
    window.hello();
    //-->
    </script>

    如果运行了这段代码,会弹出“hello,ajax!”的窗口,这正是执行hello()函数的结果。那为什么hello()变成了window对象的方法呢?因为在一个页面内定义的所有全局变量和全局函数都是作为window对象的成员。例如:

    var a=1;
    alert(window.a);

    就会弹出对话框显示为1。同样的原理,在不同框架之间共享变量和函数,就是要通过window对象来调用。
    例如:一个商品浏览页面由两个子框架组成,左侧表示商品分类的链接;当用户单击分类链接时,右侧显示相应的商品列表;用户可以单击商品旁的【购买】链接将商品加入购物车。
    在这个例子中,可以利用左侧导航页面来存储用户希望购买的商品,因为当用户单击导航链接时,变化的是另外一个页面,即商品展示页面,而导航页面本身是不变的,因此其中的JavaScript变量不会丢失,可以用来存储全局数据。其实现原理如下:
    假设左侧页面为link.html,右侧页面为show.html,页面结构如下:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <html>
    <head>
    <title> New Document </title>
    </head>
    <frameset cols="20%,80%">
       <frame src="link.html" />
       <frame src="show.html" />
    </frameset>
    </html>

    在show.html中展示的商品旁边可以加入这样一条语句:
    <a href="void(0)" >加入购物车</a>
    其中link表示导航框架,在link.html页面中定义了arrOrders数组来存储商品的id,函数addToOrders()用来响应商品旁边【购买】链接的单击事件,它接收的参数id表示商品的id,例子中是一个id为32068的商品:

    <script language="JavaScript" type="text/javascript">
    <!--
    var arrOrders=new Array();
    function addToOrders(id){
       arrOrders.push(id);
    }
    //-->
    </script>

    这样,在结帐页面或是购物车浏览页面就可以用arrOrders来获取所有准备购买的商品。
    框架可以使一个页面划分为功能独立的多个模块,每个模块之间彼此独立,但又可以通过window对象的引用来建立联系,是Web开发中的一个重要机制。在 Ajax开发中,还可以利用隐藏框架实现各种技巧,在后面介绍Ajax实例编程时可以发现,无刷新上传文件以及解决Ajax的前进后退问题都会用到这种技术。

    Javascript 子级页调用父级页的函数

    通过iframe调用页面,然后在子级页面执行父级的函数

    parent.window.[函数名称]