2006-10
02

今天客户发过来一个bug报告,说发送邮件时内容中书写はぁ~,收信时会显示成はち。 懂日文的朋友大概能明白,感叹词はぁ~怎么就变成了蜜蜂はち呢?

后来找到了原因。我们的邮件系统是用 Perl 写成的。其中有一个空格删除功能, 就是在显示时将邮件中的全角空格全部删除,其实现方法如下:

$body =~ s/ //g;

看起来似乎没有问题,但就是这条语句将はぁ~变成了はち。日文 euc-jp 编码下, 这几个字符串的编码如下:

字符串编码
はぁ~A4CF A4A1 A1C1
はちA4CF A4C1
全角空格A1A1

的后半个字符和的前半个字符恰好都是 A1,所以就被删除了,于是就出现了有意思的乱码现象。 修改方法也比较简单,只要正确识别出每个汉字的起止位置即可。

my $twoBytes   = '[\x8E\xA1-\xFE][\xA1-\xFE]';
my $threeBytes = '\x8F[\xA1-\xFE][\xA1-\xFE]';
while($body =~ s/\G(($twoBytes|$threeBytes|[\x00-\x7F])+?) /$1/g){};  # 识别汉字,如果汉字后面有空格则删除
$body =~ s/^ //g;        # 最后删除最开始处的全角空格

2006-10
01

mysql 从版本 4.1 起增加了多国语言字符集功能。 数据在插入到数据库或者从数据库中取出时,mysql会自动进行字符集变换。 在创建数据库时必须要指定数据库字符编码,而客户端在连接mysql时也必须要指定客户端字符编码。 假设数据库字符编码utf8,而客户端字符编码gb2312, 那么执行select时mysql会将字符串从 utf8 转换成 gb2312, 而在执行 insert、update等时会将客户端输入的数据从 gb2312 转换成 utf8。

WordPress的数据使用 UTF-8 编码,因此在 mysql-5.0中创建数据库时应当将字符集指定为 utf8。 遗憾的是 php 等脚本语言不会自动设置客户端字符编码,因此mysql会选择默认的 latin1 , 这样在执行 select 时mysql会将数据从utf-8转换到latin1,造成乱码现象。

解决方法就是在执行 mysql_connect 之后执行以下语句

mysql_query("SET NAMES utf8");

使用phpMyAdmin-2.8.0.2完整的升级方法如下:

  1. 从原有的数据库中导出表结构和数据。
  2. 在mysql-5.0中创建数据库,设置字符校对为 utf8_general_ci。
  3. 向数据库中导入数据,导入时设置数据编码为utf8。
  4. 修改 wp-includes/wp-db.php,在wpdb类的wpdb函数中(57行前后)添加以下内容。
    function wpdb($dbuser, $dbpassword, $dbname, $dbhost) {
        $this->dbh = @mysql_connect($dbhost, $dbuser, $dbpassword);
        ......
        $this->query("SET NAMES utf8");          // 添加这一行
        $this->select($dbname);
    }
mysql-5-update.png

2006-10
01

本文参考了 mod_perl 的官方文档之一, 但并不是原文档的翻译。

阅读全文 »
2006-09
30

Synergy的确是一个不可思议的软件, 在此先谢谢 smalldust 的推荐。

Synergy可以算作一款远程控制软件。一般的远程控制软件都是将服务器的画面提供给客户端使用, 而Synergy的创意很独特,它将客户端的键盘和鼠标提供给服务器使用。 这样如果你有多台电脑并且每台电脑都有自己的显示器,你可以通过 Synergy 用一组键盘和鼠标控制所有电脑, 而且每台电脑的屏幕可以连接起来,就像在同一台电脑上使用多个显示器一样。 下面介绍一下使用方法,所用版本为 1.3.1。

阅读全文 »
2006-09
30

用过 del.icio.us 的人一定知道,该网站的标题栏后面有一个标签输入框, 在输入框中输入标签名即可直接跳转到想要看的标签,而不必从纷繁芜杂的标签云中去寻找。 如果你在 WordPress 中添加了标签云, 一定也想在标题栏后添加一个类似于 del.icio.us 那样的输入框吧。

这里是仿照 del.icio.us 制作的标签输入框代码。attachcrumb.zip 使用方法如下。

  1. 首先按照这个方法打开永久链接。
  2. 下载 prototype,然后将 prototype 和本文附带的 crumb.js 放到你的主题目录下的 js/ 目录下,然后在主题的 header.php 的 <head> 标记内加入以下代码。
    <script type="text/javascript" src="<?php bloginfo('template_directory'); ?>/js/prototype.js"></script>
    <script type="text/javascript" src="<?php bloginfo('template_directory'); ?>/js/crumb.js"></script>
  3. 在你想加入标签输入框的地方加入以下代码(通常是在blog的标题后)。
    <h1 id="pagetitle">
      <a id="top"></a><a href="<?php echo get_settings('home'); ?>/"><?php bloginfo('name'); ?></a>
      <!-- 上面是blog标题,下面是标签输入框的代码 -->
      / <span id="crumb"><?php echo single_cat_title(); ?></span>
      <script>
        if(Crumb) 
          Crumb.go('crumb', '<?php echo get_settings('home').get_settings('category_base').'/'; ?>');
      </script>
      <!-- 标签输入框代码结束 -->
    </h1>
  4. 最后在主题的 style.css 中增加以下代码,以定义标签输入框的样式。
    span#crumb input {
      font-size: 0.7em;
      font-family:verdana,sans-serif;
      background-color: #FFFFFF;
      border: solid 1px #DDDDDD;
      color: #808080;
    }
    span#crumb input.crumb-focus {
      border: solid 1px #000000;
      color: #000000;
    }

2006-09
28

如何在Linux下创建这样一个程序,执行之后返回shell,但程序本身驻留在内存之中继续执行?其实很简单,创建一个子进程,然后父进程结束即可。例如下面的Perl程序:

#!/usr/bin/perl
exit if fork();       # 创建子进程,然后父进程退出
while (1) { sleep 1; }       # 测试用死循环

不过需要考虑到一点,守护进程通常在系统启动时以root身份启动,但是由于安全问题,通常并不以root身份运行。这一点使用perl如何实现呢?可以使用下面的 sudo 函数。

sub sudo {
    my ($user, $group) = @_;
    my $uid = (getpwnam($user))[2];
    my $gid = (getgrnam($group))[2];
    ($(, $)) = ($gid, "$gid $gid");
    ($<, $>) = ($uid, $uid);
}

所以,一个基本的守护程序应当这样写:(sudo函数代码省略)

#!/usr/bin/perl
&sudo("myuser", "mygroup");     # myuser、mygroup为启动守护进程的用户和组
exit if fork();
while (1) { sleep 1; }

2006-09
28
信号动作解释
SIGHUP1终端线路挂断
SIGINT2Term键盘输入的中断命令,从终端输入 Ctrl-C 时发生
SIGQUIT3Core键盘输入的退出命令
SIGILL4Core错误指令
SIGABRT6Coreabort(3)发出的中止信号
SIGFPE8Core浮点数异常
SIGKILL9TermKILL信号
SIGSEGV11Core非法内存访问
SIGPIPE13Term管道断开
SIGALRM14Termalarm(2)发出的中止信号
SIGTERM15Term强制中止信号
SIGUSR130,10,16Term用户自定义信号1
SIGUSR231,12,17Term用户自定义信号2
SIGCHLD20,17,18Ign子进程中止信号
SIGCONT19,18,25Cont继续执行一个停止的进程
SIGSTOP17,19,23Stop非终端来的停止信号
SIGTSTP18,20,24Stop终端来的停止信号
SIGTTIN21,21,26Stop后台进程读终端
SIGTTOU22,22,27Stop后台进程写终端

常用的包括 SIGHUP(服务进程重起)、SIGKILL(进程结束)等。


2006-09
28

WordPress有个很好用的插件:Weighted Categories, 它能够将分类名显示成tag cloud,即文章数多的分类使用大号字体,文章数少的分类使用小号字体。 但是这个插件有两个问题,一是最后一个分类的链接不正确,这一点官方主页上也有人提出过; 二是各个级别的分类的样式是通过计算得出的,无法自定义样式。

针对以上两个问题,我修改了这个插件,并将其汉化。新的插件可以在这里下载。attachweighted-categories.zip

使用时将 weighted-categories.php 放到 wp-content/plugins 下,然后在管理面板中激活该插件。 然后在模板中加入以下的代码以显示tagcloud。

<div id="tagcloud">
<?php weighted_categories(1, 10, ""); ?>
</div>

然后需要在模板的 style.css 中加入你自己的分类级别样式定义(必须,否则各个级别显示出来都一个样)。 附带的 style-sample.css 为示例。

修改后的 weighted_categories 定义如下:

function weighted_categories($minlevel=1, $maxlevel=10, $exclude_categories)
  - $minlevel: 最小级别的编号
  - $maxlevel: 最大级别的编号
  - $exclude_categories: 不想显示的分类id,使用逗号分割,例如 "1,25"表示不显示 id 为 1 或 25 的分类

当然,为了让这些标签看起来更像真正的标签,我们需要在WordPress的选项中打开永久链接, 并在选项->永久链接分类基础选项中填入“/tag”,这样分类的链接就会显示为 /tag/分类名。


2006-09
23

下载并安装 httpd 2.2。

$ tar xjvf httpd-2.2.3.tar.bz2
$ cd httpd-2.2.3/
$ ./configure --enable-rewrite --enable-so
$ make
$ sudo make install

下载并安装 mysql-3.23

$ sudo tar xzvf mysql-3.23.58-pc-linux-i686.tar.gz -C /usr/local/mysql
$ sudo groupadd mysql
$ sudo useradd -d /usr/sbin -s /bin/false -g mysql mysql
$ sudo chown -R mysql.mysql /usr/local/mysql
$ cd  /usr/local/mysql
$ sudo ./scripts/mysql_install_db
$ sudo cp support-files/mysql.server /etc/init.d/mysql
$ /etc/init.d/mysqld start

下载并安装 php 5.1.6。

$ sudo apt-get install flex bison libxml2-dev
$ tar xjvf php-5.1.6.tar.bz2
$ cd php-5.1.6/
$ ./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-gd
                  --with-gettext --with-mysql --with-zlib-dir=/usr/lib 
                  --with-mysql=/usr/local/mysql

2006-09
22

在 /boot/grub/menu.lst 的内核命令后加上 vga=nnn (nnn为整数)参数可以使用高分辨率的命令行界面。其值如下。

640x480800x6001024x7681280x1024
8bit769771773775
15bit784787790793
16bit785788791794
24bit786789792795