2010年5月21日 | 分类: 兴趣所在 | 标签: ,

用于判断ip的包含,冲突

define('MASK_NUM_V4', '32');
define('MASK_NUM_V6', '64');

/**
 * exchange ipv6 text to array(int[high], int[low]) for 64-bit system
 * @param $ipv6_address(string) ipv6 text
 * @return array(high(64bit), low(64bit))
 * @author xw
 */
function ipv62long($ipv6_address){/*{{{*/
	$res = array();
	$num = 0;
	$i = 0;

	$str = inet_pton($ipv6_address);
	while($i <= 15){
		$num = $num  << 8;
		$num += ord($str[$i]);
		if(($i + 1) % 8 == 0){
			$res[] = $num;
			$num = 0;
		}
		$i ++;
	}
	return $res;
}/*}}}*/

/**
 * exchange array(int[high], int[low]) to ipv6 text for 64-bit system
 * @param array(high(64bit), low(64bit))
 * @return String ipv6 text
 * @author xw
 */
function long2ipv6($ipv6_num = array()){/*{{{*/
	$i = $j = 0;
	$res = "";
	while($i <= 1){
		$j = 0;
		$str = "";
		$num = $ipv6_num[$i];
		while($j <= 7){ 			
			$str = chr($num % 256) . $str; 	 			
			$num = $num >> 8;
			$j ++;
		}
		$res .= $str;
		$i ++;
	}
	return inet_ntop($res);
}/*}}}*/

/**
 * get a mask with $n-1
 * @param $n(int) number of 1 from left side
 * @param $t(int) max number of mask MASK_NUM_V4 default
 * @return int of mask value
 * @author xw
 */
function get_mask($n, $t = MASK_NUM_V4){/*{{{*/
	$ret = 0;
	$n = intval($n);
	while($t > 0){
		$ret = $ret << 1; 		
		if($n > 0){
			$ret = $ret | 1;
			$n --;
		}
		$t --;
	}
	return $ret;
}/*}}}*/

/**
 * get a ipv6 mask with $n-1
 * @param $n(int) number of 1 from left side
 * @return int of mask value
 * @author xw
 */
function get_mask_v6($n){/*{{{*/
	return get_mask($n, MASK_NUM_V6);
}/*}}}*/

/**
 * test whether is equal for two ip number under the mask
 * @param $num1(int) number of ip
 * @param $num2(int) number of ip
 * @param $mask number of ip
 * @param $type(int) max number of mask MASK_NUM_V4 default
 * @return boolean true if equal
 * @author xw
 */
function mask_equal($num1, $num2, $mask, $type = MASK_NUM_V4){/*{{{*/
	$num1 = intval($num1);
	$num2 = intval($num2);
	$mn = get_mask($mask,$type);
	return (($num1 & $mn) === ($num2 & $mn));
}/*}}}*/

/**
 * test whether is equal for two ip number under the mask
 * @param $num1(int) number of ip
 * @param $num2(int) number of ip
 * @param $mask number of ip
 * @return boolean true if equal
 * @author xw
 */
function mask_equal_v6($num1, $num2, $mask){/*{{{*/
	return mask_equal($num1, $num2, $mask, MASK_NUM_V6);
}/*}}}*/

/**
 * test whether $ip1 and $ip2 will include each other return the wide one
 * @param $ip1(array("ip", "mask")) number of ip
 * @param $ip2(array("ip", "mask")) number of ip
 * @param $type(int) max number of mask MASK_NUM_V4 default
 * @return the wide one or false
 * @author xw
 */
function ip_conflict($ip1, $ip2, $type = MASK_NUM_V4){/*{{{*/
	if($ip1['mask'] > $ip2['mask']){
		$mask = $ip2['mask'];
		if(mask_equal($ip1['ip'], $ip2['ip'], $mask, $type)){
			return $ip1;
		}
	}else if($ip1['mask'] < $ip2['mask']){
		$mask = $ip1['mask'];
		if(mask_equal($ip1['ip'], $ip2['ip'], $mask, $type)){
			return $ip2;
		}
	}else{
		if($ip1['ip'] == $ip2['ip'])
			return $ip1;
	}
	return false;
}/*}}}*/

/**
 * test whether $ip1 and $ip2 will include each other return the wide one
 * @param $ip1(array("ip", "mask")) number of ip
 * @param $ip2(array("ip", "mask")) number of ip
 * @return the wide one or false
 * @author xw
 */
function ip_conflict_v6($ip1, $ip2){/*{{{*/
	return ip_conflict($ip1, $ip2, MASK_NUM_V6);
}/*}}}*/
2010年4月26日 | 分类: 兴趣所在 | 标签: ,

偶然碰到关于rss标准中的时间的定义的问题,上网查了下rss2.0的标准看到时间的定义是遵循RFC822中的一段定义

     date-time   =  [ day "," ] date time        ; dd mm yy
                                                 ;  hh:mm:ss zzz

     day         =  "Mon"  / "Tue" /  "Wed"  / "Thu"
                 /  "Fri"  / "Sat" /  "Sun"

     date        =  1*2DIGIT month 2DIGIT        ; day month year
                                                 ;  e.g. 20 Jun 82

     month       =  "Jan"  /  "Feb" /  "Mar"  /  "Apr"
                 /  "May"  /  "Jun" /  "Jul"  /  "Aug"
                 /  "Sep"  /  "Oct" /  "Nov"  /  "Dec"

     time        =  hour zone                    ; ANSI and Military

     hour        =  2DIGIT ":" 2DIGIT [":" 2DIGIT]
                                                 ; 00:00:00 - 23:59:59

     zone        =  "UT"  / "GMT"                ; Universal Time
                                                 ; North American : UT
                 /  "EST" / "EDT"                ;  Eastern:  - 5/ - 4
                 /  "CST" / "CDT"                ;  Central:  - 6/ - 5
                 /  "MST" / "MDT"                ;  Mountain: - 7/ - 6
                 /  "PST" / "PDT"                ;  Pacific:  - 8/ - 7
                 /  1ALPHA                       ; Military: Z = UT;
                                                 ;  A:-1; (J not used)
                                                 ;  M:-12; N:+1; Y:+12
                 / ( ("+" / "-") 4DIGIT )        ; Local differential
                                                 ;  hours+min. (HHMM)

看来nforum中的rss生成器还是挺标准的,之后根据rss2.0修改了下rss生成器的代码,验证了传入的数组的key,代码如下

/****************************************************
 * FileName: app/vendors/inc/rss.php
 * Author: xw
 * Last Modified: 2010-04-26 22:10
 *****************************************************/

/**
 * class Rss
 * Rss generator
 *
 * @author xw
 */
class Rss {

        /**
         * rss channel array
         * @var array $channel
         * @access public
         */
        public $channel = array();

        /**
         * rss item array
         * @var array $items
         * @access public
         */
        public $items = array();

        /**
         * required channel elements
         * @var array $_channel
         * @access private
         */
        private $_channel = array("title", "link", "description");

        /**
         * optional channel elements
         * @var array $_channelTag
         * @access private
         */
        private $_channelTag = array("language", "generator", "lastBuildDate", "copyright", "managingEditor", "webMaster", "pubDate", "category", "docs", "cloud", "ttl", "image", "rating", "textInput", "skipHours", "skipDays");

        /**
         * optional item elements
         * @var array $_itemTag
         * @access private
         */
        private $_itemTag = array("title", "link", "author", "pubDate", "guid", "comments", "description", "enclosure", "source");

        /**
         * rss version
         * @var string $_version
         * @access private
         */
        private $_version = "2.0";

        /**
         * rss encode
         * @var string $_encoding
         * @access private
         */
        private $_encoding = "gb2312";

        /**
         * function __construct
         *
         * @param array $c channel data
         * @param array $i item data
         * @return Rss object
         * @access public
         * @throws RssException
         */
        public function __construct($c, $i = array()){
                if(!is_array($c) || !is_array($i))
                        throw new RssException();
                $keys = array_keys($c);
                foreach($this->_channel as $v){
                        if(!in_array($v, $keys))
                                throw new RssException();
                }
                $this->channel = $c;
                $this->items = $i;
        }

        public function getRss(){
                $ret = "";
                $ret .= $this->_getHeader();
                $ret .= $this->_getChannel();
                $ret .= $this->_getItems();
                $ret .= $this->_getFooter();
                return $ret;
        }

        private function _getChannel(){
                $ret = "";
                foreach($this->channel as $k => $v){
                        if(!in_array($k, $this->_channelTag) && !in_array($k, $this->_channel))
                                continue;
                        if($k === "lastBuildDate" || $k === "pubDate")
                                $v = gmdate("D, d M Y H:i:s", $v) . " GMT";
                        $ret .= "\n\t\t<$k>$v</$k>";
                }
                return $ret;
        }

        private function _getItems(){
                $ret = "";
                foreach($this->items as $item){
                        if(is_array($item)){
                                $ret .= "\n\t\t";
                                foreach($item as $k => $v){
                                        if(!in_array($k, $this->_itemTag))
                                                continue;
                                        if($k === "pubDate")
                                                $v = gmdate("D, d M Y H:i:s", $v) . " GMT";
                                        $ret .= "\n\t\t\t<$k>$v</$k>";
                                }
                                $ret .= "\n\t\t";
                        }
                }
                return $ret;
        }

        private function _getHeader(){
                return <<<EOT
<?xml version="1.0" encoding="{$this->_encoding}" ?>
<rss version="{$this->_version}">
        <channel>
EOT;
        }

        private function _getFooter(){
                return <<<EOD
\n      </channel>
EOD;
        }
}
class RssException extends Exception{}
2010年4月22日 | 分类: 他山之石, 兴趣所在 | 标签: ,
2010年4月18日 | 分类: 兴趣所在 | 标签: , ,

对新论坛的重构基本告一段落,基础的结构有一定的修改,毕竟看完design pattern 后对自己当初的设想产生了怀疑。不过介于kbs的限制,只能尽力的把所有的设计做的更符合人的思维模式。如果把kbs比做一个女人的话,我只能在外表上去装饰她,却不可能完全的得到她,这对于一个异性来说是多么痛苦的一件事啊!

blog很久没有关心了,前段时间正好赶上弄辅导员博客,稍微研究了一下WordPress Mu,看了下几个主题。不过悲剧的是在刚搭建完后,WordPress 3.0的新闻就铺天盖地了,而且imba的更新居然是是整合了 wpmu,当时只能做耸肩摇头状。今儿有时间特意从官方的svn 上checkout了最新的WordPress 3.0 先自己玩玩,从使用的过程中看还是有很多小的改动,毕竟是svn中的版本,很多都标明还在开发中,比如外观中的多了个Menus工具,ms是整合了连接,分类,页面的东西,不过真没研究明白是做什么的。主题方面加上了大家都在用的inove和block,都是出自mg12,简单的主题往往让人感觉很好。辅导员博客也需要很多主题,以后陆续会换些主题,政治需要啊。最后把代码高亮插件尝试了wp-syntax和现在用的Syntax Highlighter and Code Prettiffier WordPress Plugin ,效果挺不错的,在各类评论文章中都获得好评,下面贴一下代码高亮标签,便于查阅。

Brush name Brush aliases File name
ActionScript3 as3, actionscript3 shBrushAS3.js
Bash/shell bash, shell shBrushBash.js
ColdFusion cf, coldfusion shBrushColdFusion.js
C# c-sharp, csharp shBrushCSharp.js
C++ cpp, c shBrushCpp.js
CSS css shBrushCss.js
Delphi delphi, pas, pascal shBrushDelphi.js
Diff diff, patch shBrushDiff.js
Erlang erl, erlang shBrushErlang.js
Groovy groovy shBrushGroovy.js
JavaScript js, jscript, javascript shBrushJScript.js
Java java shBrushJava.js
JavaFX jfx, javafx shBrushJavaFX.js
Perl perl, pl shBrushPerl.js
PHP php shBrushPhp.js
Plain Text plain, text shBrushPlain.js
PowerShell ps, powershell shBrushPowerShell.js
Python py, python shBrushPython.js
Ruby rails, ror, ruby shBrushRuby.js
Scala scala shBrushScala.js
SQL sql shBrushSql.js
Visual Basic vb, vbnet shBrushVb.js
XML xml, xhtml, xslt, html, xhtml shBrushXml.js
2010年4月17日 | 分类: 兴趣所在 | 标签:

如果你的应用程序有很多 JOIN 查询,你应该确认两个表中Join的字段是被建过索引的。这样,MySQL内部会启动为你优化Join的SQL语句的机制。
而且,这些被用来Join的字段,应该是相同的类型的。例如:如果你要把 DECIMAL 字段和一个 INT 字段Join在一起,MySQL就无法使用它们的索引。对于那些STRING类型,还需要有相同的
字符集才行。(两个表的字符集有可能不一样)

今天就碰到了char的字符集不一样导致explain出来的结果是全表扫描,特别伤

2009年12月14日 | 分类: 他山之石, 兴趣所在 | 标签: ,

just mark

http://daniel.carrera.bz/2008/12/comparison-of-php-frameworks-part-0/
http://daniel.carrera.bz/2009/01/comparison-of-php-frameworks-part-i/

老外写文章真是负责,为了写这篇文章花了那么久的时间做测试,cake的确在各项指标中略占下风,文章中提到的一些不足之处也在开发中遇到了,还好稍微改了下核心代码,否则严重影响效率。
看来老外还是很偏向于yii和CI的,可以研究下了。。。

2009年8月3日 | 分类: 兴趣所在 | 标签: ,

测试环境:apache2.2+php5.2+ie6/firefox3.5+jquery1.3

服务器>客户端
1.通过服务器的编码指定在客户端能正常显示,比如服务器输出gb编码的内容,在header中指定为gbk编码,ajax返回的数据可以正常显示。
2.若使用json作为数据载体,用一般的json库对gb编码的中文字符无法解析将返回null,故可自定义json的解析忽略对异常编码的判断,就可以解析gb下的数据结构了

class BYRJSON {
    public static function encode($var){
        switch (gettype($var)){
            case 'boolean':
                return $var ? 'true' : 'false';

            case 'NULL':
                return 'null';

            case 'integer':
                return (int) $var;

            case 'double':
            case 'float':
                return (float) $var;

            case 'string':
                return '"' . $var  . '"';   

            case 'array':
                if (is_array($var) && count($var) && (array_keys($var) !== range(0, count($var) - 1))) {
                    $prop= array_map(array(self, "_name_value"), array_keys($var), array_values($var));
                    return '{' . join(',', $prop) . '}';
                }   
                $element = array_map(array(self, "encode"), $var);
                return '[' . join(',', $element) . ']';

            case 'object':
                $vars = get_object_vars($var);
                $prop= array_map(array(self, '_name_value'), array_keys($vars), array_values($vars));
                return '{' . join(',', $prop) . '}';
        }   
    }   

    private static function _name_value($name, $value){
        return self::encode(strval($name)) . ':' . self::encode($value);
    }
}

客户端>服务器
1.不同的浏览器对于ajax的实现各有不同,ie采用一种明文发送的方法而ff会自动将中文编码为web编码。但是,不管客户端的编码是什么以及所要传输的中文是什么编码,js的encodeURI函数都会将其编码为utf8的web编码。
2.解决不同浏览器的ajax的编码不一致的方法就是将发送的数据两次web编码,在服务器做一次解码。对于gb的编码在服务器还需要对提交的中文进行转编码。
3.ie在ajax编码异常(内容和header中的编码不一致的情况)时,js可能会出现bug,即不执行。

2009年7月27日 | 分类: 兴趣所在 | 标签: ,

转自:http://www.blueidea.com/tech/web/2009/6909.asp

[参与测试的浏览器:IE6 / IE7 / IE8 / FF3.5 / OP9.6 / SF4 / Chrome2 ]
[操作系统:Windows]

本教程旨在实现lightBox时的样式与行为分离,减少JS在各方面(全屏遮蔽、ie6中遮蔽select、双向居中、高度自适应内容等)的工作。

先上代码:

提示:你可以先修改部分代码再运行。

这个lightBox具备以下特性,大家可以通过修改代码测一测 ^-^:

在页面中任意一位置点开,均能完美遮屏(此时无法直接控制包括滚动条在内的任意元素),IE6中无须隐藏即能遮蔽select元素(iframe遮蔽法的缺陷:遮蔽后,如果拖动滚动条,select仍会移至顶层)。
lightBox的高度自适应其内容,并呈现完美的居中状态。
内容为单行时,居中显示;内容为多行时,居左显示;内容高度使lightBox超过屏高时呈现滚动条,并居顶显示,读者能完整阅读。
如有兴趣,构成这个lightBox的以下小技巧可供您参详:

1. 全屏遮蔽的方法:

A. 隐藏html/body的滚动条。
B. 用一个div做遮罩,再用一个div做带有滚动条的页面,一个叠上面,一个叠下面。

运行代码框

提示:你可以先修改部分代码再运行。

2. 单行居中,多行居左的方法(看demo吧,表述能力有限):

提示:你可以先修改部分代码再运行。

3. 使用inline-block实现未知高度垂直居中的方法(看图和demo吧,表述能力有限):

图示:
位置狂度垂直居中

代码演示:

提示:你可以先修改部分代码再运行。

存在的两个细节性问题:

1. 大家可以看到完整demo中并未出现font-size:0;,而在垂直居中法中却出现了。
因为font-size:0在完整demo中,将使firefox3.5中读者完整阅读时lightBox的鼠标滚轮失效,原因不详,这一点大家可以作情处理。
2. maxHeight这东西只能放在lightBoxContent的后面,因为在opera9.6中会出现bug,囧。

2009年7月27日 | 分类: 兴趣所在 | 标签: ,

一直没怎么深入的研究这个基础框架,最近跟随着官方文档好好的琢磨了一下,体验了一下这个被大牛们推荐的东西,下面是一些感悟。

人人都说他是rails在php上的翻版,可惜没接触过rails,整体的结构俨然是MVC的模式,zend等其他框架也遵循这种整体设计思想。有少许不同的地方,cakephp的MVC耦合度比zend要高上许多,cakephp中view和model在核心库中完全连在了一起,这对于view和model的替换产生了一定麻烦,比如要换一个view的表现或是自己实现一些独立的model。
对于view的替换,如果要从controller部分将view斩草除根那么框架本身的helpers,layout就根本用不到,cake没有提供一些有效的接口来规范核心的调用,这点zend似乎要做的好些(记得是有一个viewRender的helper用来设定具有实现接口的view),如果要替换视图现在也只能在controller上重写尽量保证能和controller高耦合。
view其实还好对于model的剥离来说最后只能修改核心库了。cake的model向来不被人看好,甚至有点kb,类的实现及其复杂,对于model的载入也令人有点费解,按照文档所说,除非你你指定,否则会自动加载与controller同名的model,而且目前还没发现核心库没有提供取消这种机制的方法。也就是说你不想用他的model也得用。最后迫不得已只能改核心的代码将model的载入删去了。。。
以上的剥离结果导致的是一些变量的浪费,显然不可能在controller中把所有涉及view和model的部分全部删去,现在也就能做到阻止了他们的自动联系,打到了初期的要求。

其实这次选择cake还是有一定道理的,为了能实现基本的MVC,zend太庞大了,cake相对于它要简单许多。但cake的自由度降低了满多,zend不愧是官方的东西。
当然了,框架毕竟是框架,整体的设计应该在框架之上,用框架来弥补设计的不足。

2009年7月14日 | 分类: 他山之石, 兴趣所在 | 标签:

原文地址:http://www.ibm.com/developerworks/cn/aix/library/au-spunix_greattools/index.html?ca=drs-cn-0713

Martin Streicher, Web 开发人员, Freelance

2009 年 7 月 13 日
UNIX® 工具一直在变化。本文介绍 10 个有用的工具,其中一些是您以前可能不太关注的工具,一些是新工具。
与日常用语一样,UNIX 工具一直在变化。经常会出现新工具,同时老工具常常会改进以适应新的最佳实践。一些工具非常常用,其他工具不太常用。一些工具经久不衰,有些工具完全过时了。为了顺畅地操作 UNIX,您必须了解最新的 “行话”。

表 1 列出了 对话 UNIX 系列中以前讨论过的 11 个重要的软件包。
表 1. 重要的 UNIX 工具

名称 用途
Cygwin 一种适用于 Windows? 操作系统的与 UNIX 相似的 shell 和构建环境
fish 一种交互性很强的 shell,具有针对命令名、选项和文件名的自动展开和语法彩色标记功能
locate 构建并搜索所有文件的数据库
rename 对大型文件集合进行批量重命名
rsync 高效地本地或远程同步文件和目录
Screen 创建和管理虚拟的持久的控制台
Squirrel 一种跨平台的脚本编程 shell
tac 以相反的次序输出输入,首先输出最后一行(tac 的作用与 cat 相反)
type 判断一个命令是别名、可执行程序、内置的 shell 还是脚本
wget 使用命令行下载文件
zsh 一种高级的 shell,提供自动补全、高级的操作数重定向和高级替换

在这一期中,我们讨论另外 10 个实用程序和应用程序,它们可以扩展或改进现有的更著名的 UNIX 包。它们涉及从通用存档转换器到高速 Web 浏览器的多个领域。

根据您使用的 UNIX 风格不同,有时候必须安装新的软件包。可以从源代码构建它们,如果包管理软件提供等效的二进制包,也可以直接安装,这会节省时间和精力。例如,如果使用 Debian 风格的 Linux?,那么可以使用 apt-get 直接安装本期讨论的许多实用程序。


关于screen的用法

原文地址:http://www.mangbar.com/document/8a80809d19d030d10119d13f81420237

开始使用Screen

简 单来说,Screen是一个可以在多个进程之间多路复用一个物理终端的窗口管理器。Screen中有会话的概念,用户可以在一个screen会话中创建多 个screen窗口,在每一个screen窗口中就像操作一个真实的telnet/SSH连接窗口那样。在screen中创建一个新的窗口有这样几种方 式:

1.直接在命令行键入screen命令

[root@tivf06 ~]# screen

Screen将创建一个执行shell的全屏窗口。你可以执行任意shell程序,就像在ssh窗口中那样。在该窗口中键入exit退出该窗口,如果这是该screen会话的唯一窗口,该screen会话退出,否则screen自动切换到前一个窗口。

2.Screen命令后跟你要执行的程序。

[root@tivf06 ~]# screen vi test.c

Screen创建一个执行vi test.c的单窗口会话,退出vi将退出该窗口/会话。

3.以上两种方式都创建新的screen会话。我们还可以在一个已有screen会话中创建新的窗口。在当前screen窗口中键入C-a c,即Ctrl键+a键,之后再按下c键,screen 在该会话内生成一个新的窗口并切换到该窗口。

screen还有更高级的功能。你可以不中断screen窗口中程序的运行而暂时断开(detach)screen会话,并在随后时间重新连接(attach)该会话,重新控制各窗口中运行的程序。例如,我们打开一个screen窗口编辑/tmp/abc文件:

[root@tivf06 ~]# screen vi /tmp/abc

之后我们想暂时退出做点别的事情,比如出去散散步,那么在screen窗口键入C-a d,Screen会给出detached提示:
暂时中断会话
点击查看原始尺寸

半个小时之后回来了,找到该screen会话:

[root@tivf06 ~]# screen -ls
There is a screen on:
        16582.pts-1.tivf06      (Detached)
1 Socket in /tmp/screens/S-root.

重新连接会话:

[root@tivf06 ~]# screen -r 16582

看看出现什么了,太棒了,一切都在。继续干吧。

你 可能注意到给screen发送命令使用了特殊的键组合C-a。这是因为我们在键盘上键入的信息是直接发送给当前screen窗口,必须用其他方式向 screen窗口管理器发出命令,默认情况下,screen接收以C-a开始的命令。这种命令形式在screen中叫做键绑定(key binding),C-a叫做命令字符(command character)。

可以通过C-a ?来查看所有的键绑定,常用的键绑定有:

C-a ? 显示所有键绑定信息
C-a w 显示所有窗口列表
C-a C-a 切换到之前显示的窗口
C-a c 创建一个新的运行shell的窗口并切换到该窗口
C-a n 切换到下一个窗口
C-a p 切换到前一个窗口(与C-a n相对)
C-a 0..9 切换到窗口0..9
C-a a 发送 C-a到当前窗口
C-a d 暂时断开screen会话
C-a k 杀掉当前窗口
C-a [ 进入拷贝/回滚模式

Screen常用选项

使用键绑定C-a ?命令可以看到, 默认的命令字符(Command key)为C-a,转义C-a(literal ^a)的字符为a:
Screen 常用选项
点击查看原始尺寸

因为screen把C-a看作是screen命令的开始,所以如果你想要screen窗口接收到C-a字符,就要输入C-a a。Screen也允许你使用-e选项设置自己的命令字符和转义字符,其格式为:

-exy x为命令字符,y为转义命令字符的字符

下面命令启动的screen会话指定了命令字符为C-t,转义C-t的字符为t,通过C-t ?命令可以看到该变化。

[root@tivf18 root]# screen -e^tt

自定义命令字符和转义字符
点击查看原始尺寸

其他常用的命令选项有:

-c file 使用配置文件file,而不使用默认的$HOME/.screenrc
-d|-D [pid.tty.host] 不开启新的screen会话,而是断开其他正在运行的screen会话
-h num 指定历史回滚缓冲区大小为num行
-list|-ls 列出现有screen会话,格式为pid.tty.host
-d -m 启动一个开始就处于断开模式的会话
-r sessionowner/ [pid.tty.host] 重新连接一个断开的会话。多用户模式下连接到其他用户screen会话需要指定sessionowner,需要setuid-root权限
-S sessionname 创建screen会话时为会话指定一个名字
-v 显示screen版本信息
-wipe [match] 同-list,但删掉那些无法连接的会话

下例显示当前有两个处于detached状态的screen会话,你可以使用screen -r 重新连接上:

[root@tivf18 root]# screen –ls
There are screens on:
        8736.pts-1.tivf18       (Detached)
        8462.pts-0.tivf18       (Detached)
2 Sockets in /root/.screen.

[root@tivf18 root]# screen –r 8736

如果由于某种原因其中一个会话死掉了(例如人为杀掉该会话),这时screen -list会显示该会话为dead状态。使用screen -wipe命令清除该会话:

[root@tivf18 root]# kill -9 8462
[root@tivf18 root]# screen -ls
There are screens on:
        8736.pts-1.tivf18       (Detached)
        8462.pts-0.tivf18       (Dead ???)
Remove dead screens with 'screen -wipe'.
2 Sockets in /root/.screen.

[root@tivf18 root]# screen -wipe
There are screens on:
        8736.pts-1.tivf18       (Detached)
        8462.pts-0.tivf18       (Removed)
1 socket wiped out.
1 Socket in /root/.screen.

[root@tivf18 root]# screen -ls
There is a screen on:
        8736.pts-1.tivf18       (Detached)
1 Socket in /root/.screen.

[root@tivf18 root]#

-d –m 选项是一对很有意思的搭档。他们启动一个开始就处于断开模式的会话。你可以在随后需要的时候连接上该会话。有时候这是一个很有用的功能,比如我们可以使用它调试后台程序。该选项一个更常用的搭配是:-dmS sessionname

启动一个初始状态断开的screen会话:

[root@tivf06 tianq]# screen -dmS mygdb gdb execlp_test

连接该会话:

[root@tivf06 tianq]# screen -r mygdb

管理你的远程会话

先 来看看如何使用screen解决SIGHUP问题,比如现在我们要ftp传输一个大文件。如果按老的办法,SSH登录到系统,直接ftp命令开始传输,之 后。。如果网络速度还可以,恭喜你,不用等太长时间了;如果网络不好,老老实实等着吧,只能传输完毕再断开SSH连接了。让我们使用screen来试试。

SSH登录到系统,在命令行键入screen。

[root@tivf18 root]# screen

在screen shell窗口中输入ftp命令,登录,开始传输。不愿意等了?OK,在窗口中键入C-a d:
管理你的远程会话
点击查看原始尺寸

然后。。退出SSH登录?随你怎样,只要别杀掉screen会话。

是 不是很方便?更进一步,其实我们可以利用screen这种功能来管理你的远程会话,保存你所有的工作内容。你是不是每次登录到系统都要开很多窗口,然后每 天都要重复打开关闭这些窗口?让screen来帮你“保存”吧,你只需要打开一个ssh窗口,创建需要的screen窗口,退出的时候C-a d“保存”你的工作,下次登录后直接screen -r 就可以了。

最好能给每个窗口起一个名字,这样好记些。使用C-a A给窗口起名字。使用C-a w可以看到这些窗口名字,可能名字出现的位置不同。使用putty:
putty
点击查看原始尺寸

使用telnet:
telnet
点击查看原始尺寸

更多Screen功能

Screen 提供了丰富强大的定制功能。你可以在Screen的默认两级配置文件/etc/screenrc和$HOME/.screenrc中指定更多,例如设定 screen选项,定制绑定键,设定screen会话自启动窗口,启用多用户模式,定制用户访问权限控制等等。如果你愿意的话,也可以自己指定 screen配置文件。

以多用户功能为例,screen默认是以单用户模式运行的,你需要在配置文件中指定 multiuser on 来打开多用户模式,通过acl*(acladd,acldel,aclchg…)命令,你可以灵活配置其他用户访问你的screen会话。更多配置文 件内容请参考screen的man页。

Martin Streicher, Web 开发人员, Freelance

2009 年 7 月 13 日

第3页/6页12345...尾页