Friday, December 01, 2006

[Window]配置sqlcmd远程连接sqlserver2005.

痛苦!!
我不是数据库管理员,对sqlserver不怎么熟悉,尤其是这些涉及到管理员的活儿. 因为sqlcmd是一个命令行的工具,可以用来做一些自动化的工作,比如自动创建数据库表模式, 自动装载数据. 本身ant又个sql的task是可以用来做这些事情的, 但是由于项目中的数据库脚本都是直接从sqlserver中导出的,完全是sqlserver的一套语法, 'sql' task不支持这些语法, 原来我是手工把数据库脚本中一些sqlserver特定的语句给删掉,比如 'GO', 'if exist...'等,但那得建立在数据库脚本比较少的基础上,而且得没有存储过程, 在现在的项目中,这些前提全被打破了, 实在没有办法,只好借助'sqlcmd'.

但是sqlcmd怎么都无法连接到到远程数据库服务器, google了一把, 也到msdn上看了不少资料, 知道关于远程连接的配置主要集中在' sqlserver外围应用配置器'上.
------------------------------------------------
1. 打开'Sqlserver 2005 Surface Area Configuration'->'按实例查看'->'Database Engine', 确保远程连接已经被设置.
2. 打开'Sqlserver Configuraion manager', 保证tcp/ip已经被激活了(服务器端与客户端).
NOTE: 上面两步都是在数据库服务器上进行的操作
3. 在客户端上, 打开'Sqlserver Configuraion manager', 保证tcp/ip已经被激活.
------------------------------------------------
在命令行窗口执行命令:
>sqlcmd -S 192.168.0.94 -U hp_ante -P hp_ante -d AnteProxy
可以连接到数据库服务器.
>sqlcmd -S hp-server-94 -U hp_ante -P hp_ante -d AnteProxy
连接也能成功.
>sqlcmd -s tcp:192.168.0.84,1433
如果'database engine'的远程连接配置的为'同时使用name piple和tcp/ip':
------------
HResult 0x2, Level 16, State 1
命名管道提供程序: 无法打开与 SQL Server 的连接 [2].
Sqlcmd: Error: Microsoft SQL Native Client : 建立到服务器的连
到 SQL Server 2005 时,默认设置 SQL Server 不允许远程连接这个
。.
Sqlcmd: Error: Microsoft SQL Native Client : 登录超时已过期.
------------
如果'database engine'的远程连接配置的为'仅使用tcp/ip':
------------
HResult 0x274D, Level 16, State 1
TCP 提供程序: No connection could be made because the target machine actively re
fused it.

Sqlcmd: Error: Microsoft SQL Native Client : 建立到服务器的连接时发生错误。连接
到 SQL Server 2005 时,默认设置 SQL Server 不允许远程连接这个事实可能会导致失败
。.
Sqlcmd: Error: Microsoft SQL Native Client : 登录超时已过期.
------------

我知道为什么最后那个命令不能成功, 后来又试了几种办法:
- 启动'Sqlserver 2005 Surface Area Configuration'中的'sqlserver browser'服务: 无法连接
唉,不管怎么样,至少有方法可以连接成功了. 如果你的sqlcmd连接不能成功, 除了上面说的配置以外,还要检查以下部分:
1. SQL Express is running (hey, gotta check)
2. SQL Browser is running
3. TCP/IP is enabled as a server protocol
4. You've created an Exception in your firewall for SQL Express
5. You've created an Exception in your firewall for SQL Browser

参考资料:
- http://blogs.msdn.com/sqlexpress/archive/2005/05/05/415084.aspx
- http://msdn2.microsoft.com/zh-cn/library/ms162773.aspx

Monday, November 20, 2006

[UBUNTU]如何在英文界面中使用中文输入法? ...以及其他的中文问题

首先说明一下我为什么要把UBUNTU的界面设置为英文。 原因很简单,其一,英文字体比较美观,我试过用中文界面,效果怎么都不能让我满意。其二,学学英文也是好的。
但是在英文界面下面使用中文输入法还不是那么简单的,嘿嘿,要胆大心细。现在的中文输入法主要是fcitx和scim。以前一直是使用scim,这东西真烦,和很多应用程序冲突,导致键盘不能输入,比如不能在firefox的地址栏输入,快捷键也失效。更受不了的是在ubuntu中居然不能重命名我自己创建的文件夹,还有realplay,acrobatreader等等都被影响不能使用(有些可以解决,有效没办法解决,至少我是不知道的,比如文件夹重命名这种事情)。那时候也试过小企鹅,但是试了几次,在英文界面下面都调不出来,所以一直是用的scim。今天小企鹅安装成功了,所以写下这些文字表示纪念。

我的ubuntu是6.10, 使用‘dist-upgrade’过来的,中间有惨痛的经历,反正最后我的数据全部被删除掉了(因为dist-upgrade之后无法起动xserver,所以只好重装,稀里哗啦的把数据分区给干掉了)。有点扯远,反正我写这些东西主要是为了记录ubuntu下中文设置的一些问题。

英文界面下使用中文输入法
------------------------------------------
1. 安装fcitx和im-switch
> sudo apt-get install im-switch libapt-pkg-perl fcitx
im-switch是一个输入法切换工具,你可以同时安装scim和fcitx,然后使用im-switch来决定使用哪个输入法。
> im-switch -s fcitx
2. 配置英文界面中文环境
修改/etc/environent
LC_CTYPE="zh_CN.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
LANGUAGE="en_US:en"
GST_ID3_TAG_ENCODING=GBK
LANG=en_US.UTF-8
其实,不需要设置的那么详细,向LC_ALL可以进行全局性配置,唉,这里我也搞不清楚每个环境变量的具体作用。
#要界面是英文,那么
LANG和LANGUAGE3必须为‘en_US.UTF-8’(必须使用UTF-8,否则不能使用中文输入法).
#要使用中文输入法
LC_CTYPE必须为"zh_CN.UTF-8"。
3.编辑X的输入法配置文件
编辑/etc/X11/Xsession.d/95xinput(没有则创建一个,xsession.d中的文件在xserver启动的时候会被自动执行,就像init.d)
export LC_CTYPE=zh_CN.UTF8
export XMODIFIERS=@im=fcitx;
export XIM=fcitx;
export XIM_PROGRAM=fcitx;
export GTK_IM_MODULE="XIM";
export QT_IM_MODULE="XIM"
fcitx
4.logout之后,登录进来就可以在英文界面下面使用中文输入法了。

使用中文字体
---------------------
1.可以参考www.ubuntu.org.cn上wiki里6.10的快速设置指南,安装文泉绎的字体.
2.然后编辑/etc/X11/xorg.conf,在其中找到‘Provide required aliases for standard names’,
在随后的alias定义中都要添加“ WenQuanYi Bitmap Song”。
3.'System->Preference->Font"中配置字体。

配置openoffice的中文字体
---------------------
我一经安装了文泉绎的字体,但是在openoffice中看不到这个字体,没办法,到openoffice的官方网站上
下了一个简体中文版的。安装之后,发现界面是成了间体中文的,但是仍然无法找到中文字体,相当的郁闷。后来
在www。ubuntu。org上面看到一个贴子也是说vopenoffice的中文字体,我也决定试一下。
1.ubuntu的字体文件在/etc/share/fonts中,我只接在/etc/share/fonts/truetype中创建了一个文件夹
‘ttf-window’,然后把c:/windows/fonts/的中文字体文件vcopy过来(也不太确定哪些是中文字体,实在不
行就把所有字体文件都搞过去)
2.打开openoffice,嘿嘿,应该能看到中文字体了(如果还是没有,尝试在/etc/share/fonts/truetype/openoffice
下为/etc/share/fonts/truetype/ttf-window中的中文字体创建符号链结).
# openoffice有个spadmin的工具,可以装载字体,没有试过,好像说不行
# openoffice自己也有一个字体文件夹$OPENOFFICE_HOME/share/fonts/truetype,可以将字体文件放进去(ttf的字体)

Friday, November 10, 2006

[UBUNTU]在ubuntu下安装trac。

首先得说trac官方网站上的安装帮助文档真是比较烂,写得稀里糊涂,如果完全按照它的文档来做肯定会抓狂,主要就是它的安装步骤次序有问题,应该先执行的居然被放到了后面。无论怎么说,最后我还是安装成功了,不过主要还得归功于ubuntu的方便,敲了几个命令,ubuntu就帮我安装好了。
1. 安装软件包
sudo apt-get install trac libapache2-svn
** 可以看的出来,一个是trac的包,一个是apache连接subversion的mod。
** 自动安装之后,至少可以找到两个应用程序/usr/bin/trac-admin /usr/bin/tracd(以standalone的方式运行trac),其他的文件可以在/usr/share/trac下找到。

2. 初始化trac环境(这里定义为/var/trac/TestEnv)
sudo mkdir /var/trac
sudo chown www-data:www-data /var/trac
** 这里使用www-data是因为apache启动之后,会设置自己的进程owner为www-data。
sudo trac-admin /var/trac/TestEnv initenv
- input the project name
- adopt the default database connection, as SqlLite is a embeded database,it has been installed.
- specify the absolute path of svn repository.
- adopt the template directory.
** 执行命令之后,可以进入/var/trac/TestEnv看到已经创建了很多文件。

3. 设置apache2
在/etc/apache2/sites-available下创建一个trac文件来定义apache的VirtualHost:

ServerAdmin webmaster@localhost
ServerName trac.hengpeng.com
DocumentRoot /usr/share/trac/cgi-bin/

Options Indexes FollowSymLinks MultiViews ExecCGI
AllowOverride All
Order allow,deny
allow from all

Alias /trac "/usr/share/trac/htdocs"


SetEnv TRAC_ENV "/var/trac/TestEnv"


DirectoryIndex trac.cgi
ErrorLog /var/log/apache2/error.trac.log
CustomLog /var/log/apache2/access.trac.log combined

同时,还需要修改/etc/apache2/apache2.conf,注释掉addHandler行使trac的CGI程序能够被执行:
# To use CGI scripts outside /cgi-bin/:
#
AddHandler cgi-script .cgi
现在,disable默认的virtualhost,同时激活trac的虚拟主机:
sudo a2ensite trac
sudo /etc/init.d/apache2 reload

4. 创建subversion的环境(好像必须新建一个仓库,使用已有的仓库在执行trac-admin命令的时候就会报错,未确认)
我将新仓库放在/var/trac/TestTrac下面:
sudo svnadmin create /var/trac/TestTrac
sudo svn import /tmp/myproject file:///var/trac/TestTrac -m "initial import"

5. 启动服务
sudo chown -R www-data /var/trac/
sudo chown -R www-data /usr/share/trac

sudo apache2 -k restart

打开浏览器,访问http://trac.hengpeng.com(当然如果你没有域名,那么需要在本地设置域名解析,一般是在hosts文件加就可以了)。

Tuesday, October 17, 2006

在UBUNTU下面配置SAMBA

基本上我的日常工作都是在ubuntu下面了,绝大多数软件都可以找到linux下面的替代品,除了那个讨厌的VSS,一直我都没有找到可以在linux下面使用的替代品。因为这样,每周我提交 周报的时候总是要先到window下面,提交了周报之后再切换回ubuntu。 我痛恨vss,但是没办法。

后来总算找到了一个复杂的workaround,就是在自己的机器上面开了postfix的ftp服务,然后再在vss服务器上面装了个UltraVNC来作远程控制。这样我就先远程控制vss服务器,然后从vss服务器上访问我本机的ftp服务下载周报文件,最后在vss服务器上提交周报。
很丑陋的解决方案,后来想到了samba,为什么不用samba直接文件共享,虽然仍然要远程控制,但是至少不用在各个文件夹里面把文件copy来copy去了。

UBUNTU 内置了samba,应该是一早就安装好的,所以直接就能用了。
一开始,我是打算共享一个ubuntu的文件夹,然后从远程window机器上面访问。配置好像是很简单的,就是从System->Administration->Share Folders里面进行配置。但是需要添加samba访问的用户,就是从window上访问临近的机器时弹出的那个用户名/密码框,如果输入ubuntu的登录名/密码那是没有用的,至少在你做特定的设置以前。
为smaba添加用户使用下面的命令:
> sudo smbpasswd -a samba
这样会为samba添加一个叫‘samba‘的用户,同时还可以指定该用户的密码。
完成这些配置之后,我就从window上面访问UBUNTU机器,比如“\\192.168.0.40”,恩,可以看的共享文件夹了,但是双击无法打开,提示‘不能访问网络名“,郁闷。基本上我的日常工作都是在ubuntu下面了,绝大多数软件都可以找到linux下面的替代品,除了那个讨厌的VSS,一直我都没有找到可以在linux 下面使用的替代品。因为这样,每周我提交 周报的时候总是要先到window下面,提交了周报之后再切换回ubuntu。 我痛恨vss,但是没办法。

后来总算找到了一个复杂的workaround,就是在自己的机器上面开了postfix的ftp服务,然后再在vss服务器上面装了个UltraVNC 来作远程控制。这样我就先远程控制vss服务器,然后从vss服务器上访问我本机的ftp服务下载周报文件,最后在vss服务器上提交周报。
很出哦

没办法,我只好反过来在ubunt中mount一个window的共享文件夹。这里假设有一台叫hp-server的机器,我设置了f://liming.l共享。这里先检查一下从ubuntu上是否能够访问hp-server的共享,可以用下面的命令:
> smbclient -L \\hp-server -U administrator (或者是//hp-server)
根据提示输入访问密码之后,下面列出了所有hp-server上的共享目录:
Password:
Domain=[HP-SERVER3] OS=[Windows 5.0] Server=[Windows 2000 LAN Manager]

Sharename Type Comment
--------- ---- -------
E$ Disk ─¼╚¤╣▓¤Ý
VSS Disk
IPC$ IPC ÈÂ│╠ IPC
D$ Disk ─¼╚¤╣▓¤Ý
liming.li Disk
Installation Disk
F$ Disk ─¼╚¤╣▓¤Ý
ADMIN$ Disk ÈÂ│╠╣▄└Ý
C$ Disk ─¼╚¤╣▓¤Ý
Domain=[HP-SERVER3] OS=[Windows 5.0] Server=[Windows 2000 LAN Manager]

Server Comment
--------- -------

Workgroup Master
--------- -------
这个说明ubuntu能访问远程window的共享目录。在进行mount之前,保证系统已经安装了smbfs,可以用> sudo apt-get install smbfs来安装,最后可以用以下命令类执行mount:
> sudo mount -t smbfs -o username=administrator,password=hpsystem //hp-server/liming.li window/
这表示//hp-server/liming.li已经被mount到本地的当前目录下的window目录,嘿嘿,总算搞定了一点!!剩下的以后再说吧。

Tuesday, October 10, 2006

公司感想

2006年7月我终于到了深圳, 主要是两个原因, 其一, 老哥总是希望我到深圳看看,要是可以,呆在深圳就更好了. 我也这么想, 如果两兄弟都在深圳的话,父母也就可以都到深圳来,也算一家团圆,也不错. 其二, 在菲尼克斯的工作实在不合我的胃口,没有挑战,而且都是做一些报表之类的烦人的东西, 既然深圳的老板答应给我更好的机会, 虽然是个民营小公司,但毕竟以前也在这里呆过三年,彼此之间有一些了解和信任,所以我想回去做一个techleader也不错,我所知道的,在这个公司是肯定够用了, 所以我决定去深圳.
今天是2006年10月7日, 距离我到深圳正好三个月,写点文字纪念一下. 其实早就想写了,前段时间也郁闷的不行,但是却一直没写,搭多数时间是躺在床上闷骚,没劲. 现在我要写下来, 是总结,也是对以后的展望.
首先,我得说深圳之行的结果大失所望, 我不认为自己得到了发挥的机会, 我对自己的角色相当迷惑. 这里得提一下我近来做人的态度(做人的态度失随着胡子,皱纹等等东西的变化而不断变化的,所以这里我强调失近来的做人态度), 很多问题我已经不愿意和人去争论了,和以前不一样, 以前要是不争个你死我活,事情不会结束. 后来慢慢长大, 长大到不愿意和人争论了,不知道这是好还是坏. 隐约想起很小的时候听过的一个故事. 说是一个路人甲到烧饼铺买烧饼, 一个烧饼三文钱, 买了两个, 老板非说是8文钱, 因为他算的是3+3=8. 老板倒不是耍赖,真的是他就那水平, 以他的智慧3+3就是等于8. 买饼的人当然不干, 两个人就争论起来. 后来老板急了, 一扯脖子说, 3+3要不是等于8, 我脑袋都给你. 后来买饼的那家伙,他老婆来了. 他老婆就跟他说, 你就给8文钱吧,免得他脑袋掉了, 他迟早得蠢死. 故事没有下文, 我想那买饼得是得蠢死. 有点扯远, 所以我现在也不太愿意争论了. 当然是不是要争论也得看场合.
....

Saturday, September 30, 2006

读书计划: Applying UML and Pattern

VOCABULARY
=====================
OCL : Object Contraint Language, one specification of UML
R&D : Research and Development
SSD : System Sequence Diagram
LRG : low representational gap
GRASP: General Responsibility Assignment Software Principle
DCD : Design Class Diagram

Read Log
=====================
[ 2006/10/08 ]
- Coupling Level
  • TypeX has an attribute (data member or instance variable) that refers to a TypeY instance, or TypeY itself.

  • A TypeX object calls on services of a TypeY object.

  • TypeX has a method that references an instance of TypeY, or TypeY itself, by any means. These typically include a parameter or local variable of type TypeY, or the object returned from a message being an instance of TypeY.

  • TypeX is a direct or indirect subclass of TypeY.

  • TypeY is an interface, and TypeX implements that interface

[ 2006/10/09 ]
- Cohesion Level
  1. Very low cohesion A class is solely responsible for many things in very different functional areas.

    • Assume the existence of a class called RDB-RPC-Interface which is completely responsible for interacting with relational databases and for handling remote procedure calls. These are two vastly different functional areas, and each requires lots of supporting code. The responsibilities should be split into a family of classes related to RDB access and a family related to RPC support.

  2. Low cohesion A class has sole responsibility for a complex task in one functional area.

    • Assume the existence of a class called RDBInterface which is completely responsible for interacting with relational databases. The methods of the class are all related, but there are lots of them, and a tremendous amount of supporting code; there may be hundreds or thousands of methods. The class should split into a family of lightweight classes sharing the work to provide RDB access.

  3. High cohesion A class has moderate responsibilities in one functional area and collaborates with other classes to fulfill tasks.

    • Assume the existence of a class called RDBInterface that is only partially responsible for interacting with relational databases. It interacts with a dozen other classes related to RDB access in order to retrieve and save objects.

  4. Moderate cohesion A class has lightweight and sole responsibilities in a few different areas that are logically related to the class concept but not to each other.

    • Assume the existence of a class called Company that is completely responsible for (a) knowing its employees and (b) knowing its financial information. These two areas are not strongly related to each other, although both are logically related to the concept of a company. In addition, the total number of public methods is small, as is the amount of supporting code.

UBUNTU的多媒体设置

作者:Karron Qiu
主页:http://karronqiu.googlepages.com
BLOG:http://spaces.msn.com/karronqiu
keyword:ubuntu dapper multimedia w32codes gstreamer libxine-extracodecs realplay


目录

安装软件解码器

很多人在 ubuntu-cn 论坛抱怨dapper中没有w32codecs,导致totem,mplayer,rhythmbox等不能播放rmvb,wmv等视频,不能播放mp3等音频。觉得ubuntu真难用。

其实windows如果不安装解码器很多东西也不能播放,比如rmvb,avi等。

好废话不用多说,我们来讲讲怎么在ubuntu dapper中安装各种解码器。

首先安装gstreamer的解码器,gstreamer是gnome主推的多媒体平台。在dapper中进行了重大升级,目前是0.10。但是默认没有安装完全,导致mp3等不能播放。所以,我们要安装 gstreamer0.10 .

sudo apt-get install gstreamer0.10-*

这条语句会把所有的gstreamer0.10的包安装上。

然后我们安装xine的解码器 libxine-extracodecs ,xine是另外一个多媒体平台,功能非常强大。我们还把系统自带的totem卸载,改为使用xine后端的totem,这样才可以播放rmvb等视频。 顺便安装上mplayer这个强大的播放器,我一般用它来播放dvd。注意如果是 amd的CPU,需要安装mplayer-k7,当然,大家也可以直接安装mplayer,这个比较通用。

sudo apt-get install libxine-extracodecs totem-xine mplayer-686 ffmpeg lame faad sox mjpegtools libxine-main1

接下来我们安装著名的视频解码器 w32codecs .这个在dapper的源里面没有包含,需要我们自己 下载

wget -c ftp://ftp.nerim.net/debian-marillat/pool/main/w/w32codecs/w32codecs_20050412-0.0_i386.deb

下载完成之后,开始安装。

sudo dpkg -i w32codecs_20050412-0.0_i386.deb

好了,现在大家的电脑应该都能够播放绝大部分多媒体文件了。

有的人可能比较喜欢realplayer,这里可以 下载安装 (我本人不是很建议使用realplay,当然使用它也没什么问题)。

wget -c ftp://ftp.nerim.net/debian-marillat/pool/main/r/realplay/realplayer_10.0.6-0.0_i386.deb

sudo apt-get install libstdc++5

sudo dpkg -i realplayer_10.0.6-0.0_i386.deb

配置字幕和软件

配置totem-xine加载字幕

ubuntu-cn一个方法 比较完美地解决了这个问题。原文是从源代码编译一个字体转换软件,如果不想编译,可以在 这里 下载别人编译好的程序,下载在拷贝到 /usr/local/bin 里面。在播放avi视频的时候,把字幕文件改成和视频文件一样的文件名就好了,totem-xine会自动加载。

如果你使用的是simsun的字体使用下面的命令(注意:请将路径改成自己的字体文件所在目录):

sudo xine-fontconv /usr/share/fonts/zh_CN/TrueType/SIMSUN.TTF simsun gb18030

如果是用的园体用下面的命令:

sudo xine-fontconv /usr/share/fonts/truetype/ttf-vera-yuan/VeraSansYuanTi-Bold.ttf simsun gb18030

大概要运行几分钟,会生成6个文件:simsun-* .现在把字体文件拷贝到

sudo cp simsun-* /usr/share/xine/libxine1/fonts

然后修改totem的配置文件:

gedit ~/.gnome2/totem_config

找到中间的项目修改为:

subtitles.separate.font:simsun
subtitles.separate.src_encoding:gb18030

配置mplayer字幕

安装mplayer之后运行的时候可能会报错,原因是找不到 ~/.mplayer/subfont.ttf .可以做一个链接(可以选择自己电脑上的中文字体)。

ln -s /usr/share/fonts/TrueType/simsun.ttc ~/.mplayer/subfont.ttf

如果是园体下面的语句

ln -sf /usr/share/fonts/VeraSansYuanTi/VeraSansYuanTi-Regular.ttf ~/.mplayer/subfont.ttf

然后在设置中把Subtitle&OSD的encoding选择为 cp936 ,把font的encoding设置 unicode ,默认字体(Text Scale)为5好像有点大,可以设置为3。

视频默认输出为x11,经过研究发现 xv 占用cpu最低,可以使用这个。如果不能全屏,修改.mplayer/config,设置

fs=no
zoom=yes

如果没有这个文件,可以自己建立。

另外,在.mplayer/下面建立一个Skin目录,里面可以放着skin文件,注意网上下载的skin都是压缩包,需要先解压。可以到这个下载 skin

另外如果是5.10里面的mplayer,界面是gtk1,看电影或者界面上会乱码。下面的命令就可以解决这个问题。

sudo cp /etc/gtk/gtkrc.zh_CN /etc/gtk/gtkrc.zh_CN.utf-8

如果文件不存在可以自己建立。

sudo gedit /etc/gtk/gtkrc.zh_CN.utf-8

拷贝下面的内容进去。

# $(gtkconfigdir)/gtkrc.zh_CN
#
# This file defines the fontsets for Chinese language (zh) using
# the simplified chinese standard GuoBiao as in mainland China (CN)
#
# 1999, Pablo Saratxaga
#

style "gtk-default-zh-cn" {
fontset = "-adobe-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1,-*-*-medium-r-normal--16-*-*-*-*-*-gb2312.1980-0,*-r-*"
}
class "GtkWidget" style "gtk-default-zh-cn"
#

热烈欢迎我的回来。

本来都已经把我的blog搬到opera的网站上去了, 现在发现还是livejournal好,至少这个编辑器相当好,而且我也喜欢那种简单朴素,带点技术味道的风格。
不过主要的是, blog在哪里不重要, 关键是你是不是记得常写blog。 我就挺失败, 有时候临睡觉了,肚子里面却琢磨文章,觉得那些东西一定要写到blog上的,结果一觉醒来就忘了这回事, 有首歌说,有钱的时候没时间,有时间的时候没钱。。。我是想写的时候不在电脑前,在电脑前又不想写。。。不知道是犯贱还是生活就是这样的乱七八糟,前后矛盾。

现在得说,我又从livijournal到blogger了。

安装邮件服务器postfix...记

Postfix比sendmail要容易伺候,起码我按照ubuntu.org.cn上的文档就可以装好,所以下面的基本上都是从Postfix 基本设置指南引用过来的。
---------------------------------------------------------------

Install Postfix

In this setup I assume that your domain is yourdomain.com and it has a valid MX record call mail.yourdomain.com. Remember to replace yourdomain.com with your actual domain in the example codes in this howto. Also I assume that you know what an MX record is. To find out MX your type in a terminal:

dig mx yourdomain.com

To install postfix

sudo apt-get install postfix

Intall mailx package for use as command mail utility program. Mail command is installed with this package.

sudo apt-get install mailx

Test your default setup

Add a user before you start this.

sudo useradd -m -s /bin/bash fmaster
sudo passwd fmaster

Test your default installation using the following code segment.

telnet localhost 25

Postfix will prompt like following in the terminal so that you can use to type SMTP commands.

Trying 127.0.0.1...
Connected to mail.fossedu.org.
Escape character is '^]'.
220 localhost.localdomain ESMTP Postfix (Ubuntu)

Type the following code segment in Postfix's prompt.

ehlo localhost
mail from: root@localhost
rcpt to: fmaster@localhost
data
Subjet: My first mail on Postfix
Hi,
Are you there?
regards,
Admin
. (Type the .[dot] in a new Line and press Enter )
quit

Check the mailbox of fmaster

su - fmaster
mail

When your type mail command an output like follows display in your terminal.

Mail version 8.1.2 01/15/2001.  Type ? for help.
"/var/mail/fmaster": 2 messages 2 new
>N 1 root@localhost Mon Mar 6 12:49 13/479 Just a test
N 2 root@localhost Mon Mar 6 12:51 15/487 My first mail
&

You will observe that mails are indexed by numbers and you can type the number of which the mail that you want to read. For example type no "2" to read the 2nd mail. The type "q" to quit. The mail will be written to a file called mbox in user's home directory. According to our example it will be /home/fmaster/mbox.

All messages in an mbox type of mailbox are concatenated and stored in a single file. The beginning of each message is indicated by a line whose first five characters are "From " and a blank line is appended to the end of each message

Setting Postfix Support for Maildir-style Mailboxes

Maildir is a format for an e-mail spool that does not require file locking to maintain message integrity because the messages are kept in separate files with unique names. A Maildir is a directory (often named Maildir) with three subdirectories named tmp, new, and cur. The subdirectories should all reside on the same filesystem.

Another reason to use Maildir format is that Courier IMAP/POP3 servers only work with Maildir format of mailboxes.

Please find out more about Maildir here

 sudo  vi /etc/postfix/main.cf

Add the following code segment:

home_mailbox = Maildir/

Comment the Line mailbox_command = procmail -a "$EXTENSION" adding a "#" at the beginning

Restart Postfix to make changes effect.

sudo  /etc/init.d/postfix restart

Test your setup again

Installing courier IMAP and POP3

sudo apt-get install courier-pop
sudo apt-get install courier-imap

= Adding local domains to postfix

sudo   vi /etc/postfix/main.cf

Add your domain to:

sudo vi /etc/postfix/main.cf

Add your domain to mydestination. Once added it should be like the following code segment.

...
mydestination = mail.fossedu.org, localhost.localdomain, localhost, yourdoamin.com
...

Add your local network to:

sudo vi /etc/postfix/main.cf

I assume that your local network is 192.168.1.0/24 and add your local network to mynetworks. Once added it should be like the following code segment.

mynetworks = 127.0.0.0/8, 192.168.1.0/24

Make Postfix to receive mail from the Internet

Set inet_interfaces = all in /etc/postfix/main.cf using:

sudo vi /etc/postfix/main.cf

Finally Restart Postfix;

sudo  /etc/init.d/postfix restart

Test your setup again using following code:

telnet mail.yourdomain.com 25
ehlo yourdmain.com
mail from: root@yourdomain.com
rcpt to: fmaster@yourdomain.com
data
Subject: My first mail for my domain
Hi,
Are you there?
regards,
Admin
. (and Enter In a new Line)
quit

Check the mailbox of fmaster

su - fmaster
cd Maildir/new
ls

Now you will see mail has a separate file

Testing Courier POP3

Type in a terminal:

telnet mail.yourdomain.com 110

Use the following example code segment for your test. Be intelligent to tweak the changes appropriately to your environment. An output like follows will display in your terminal.

Connected to mail.yourdomain.com (69.60.109.217).
Escape character is '^]'.
+OK Hello there.

Type the following code segment in the prompt provided by the Courier POP3 server. I assume that you inetligent enough not to type the lines which starts from +OK

user fmaster
+OK Password required.
pass password
+OK logged in.
quit

Testing Courier IMAP

Type in a terminal:

telnet mail.yourdomain.com 143

Use the following example code segment for your test. Be intelligent to tweak the changes appropriately to your environment. An output like follows will display in your terminal.

* OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE ACL ACL2=UNION STARTTLS XCOURIEROUTBOX=INBOX.Outbox] Courier-IMAP ready. Copyright 1998-2005 Double Precision, Inc.  See COPYING for distribution information.

Type the following code segment in the prompt provided by the Courier IMAP server.

a login fmaster password
a OK LOGIN Ok.
a logout
------------------------------------------------------------
它的用户管理用的就是linux操作系统的用户系统,所有创建一个linux用户也就创建了一个postfix用户。
文档介绍了更多, 但是我只用到这个程度,也就是文档看到这里基本上就可以配置一个可用的邮件服务器了。

如何编写一个shell脚本/Linux command manual

在Linux系统中,虽然有各种各样的图形化接口工具,但是sell仍然是一个非常灵活的工具。Shell不仅仅是命令的收集,而且是一门非常棒的编程语言。您可以通过使用shell使大量的任务自动化,shell特别擅长系统管理任务,尤其适合那些易用性、可维护性和便携性比效率更重要的任务。

  下面,让我们一起来看看shell是如何工作的:

  建立一个脚本

  Linux中有好多中不同的shell,但是通常我们使用bash (bourne again shell) 进行shell编程,因为bash是免费的并且很容易使用。所以在本文中笔者所提供的脚本都是使用bash(但是在大多数情况下,这些脚本同样可以在bash的大姐,bourne shell 中运行)。

  如同其他语言一样,通过我们使用任意一种文字编辑器,比如nedit、kedit、emacs、vi等来编写我们的shell程序。程序必须以下面的行开始(必须方在文件的第一行):

  #!/bin/sh

  符号#!用来告诉系统它后面的参数是用来执行该文件的程序。在这个例子中我们使用/bin/sh来执行程序。

  当编辑好脚本时,如果要执行该脚本,还必须使其可执行。

  要使脚本可执行:

  chmod +x filename

  然后,您可以通过输入: ./filename 来执行您的脚本。

  注释

  在进行shell编程时,以#开头的句子表示注释,直到这一行的结束。我们真诚地建议您在程序中使用注释。如果您使用了注释,那么即使相当长的时间内没有使用该脚本,您也能在很短的时间内明白该脚本的作用及工作原理。

  变量

  在其他编程语言中您必须使用变量。在shell编程中,所有的变量都由字符串组成,并且您不需要对变量进行声明。要赋值给一个变量,您可以这样写:

  变量名=值

  取出变量值可以加一个美元符号($)在变量前面:

  #!/bin/sh
  #对变量赋值:
  a="hello world"
  # 现在打印变量a的内容:
  echo "A is:"
  echo $a

  在您的编辑器中输入以上内容,然后将其保存为一个文件first。之后执行chmod +x first 使其可执行,最后输入./first执行该脚本。
  这个脚本将会输出:
  A is:
  hello world

  有时候变量名很容易与其他文字混淆,比如:

  num=2
  echo "this is the $numnd"

  这并不会打印出"this is the 2nd",而仅仅打印"this is the ",因为shell会去搜索变量numnd的值,但是这个变量时没有值的。可以使用花括号来告诉shell我们要打印的是num变量:

  num=2
  echo "this is the ${num}nd"

  这将打印: this is the 2nd

  有许多变量是系统自动设定的,这将在后面使用这些变量时进行讨论。

  如果您需要处理数学表达式,那么您需要使用诸如expr等程序(见下面)。

  除了一般的仅在程序内有效的shell变量以外,还有环境变量。由export关键字处理过的变量叫做环境变量。我们不对环境变量进行讨论,因为通常情况下仅仅在登录脚本中使用环境变量。

  Shell命令和流程控制

  在shell脚本中可以使用三类命令:

  1)Unix 命令:

  虽然在shell脚本中可以使用任意的unix命令,但是还是由一些相对更常用的命令。这些命令通常是用来进行文件和文字操作的。

  常用命令语法及功能

  echo "some text": 将文字内容打印在屏幕上

  ls: 文件列表

  wc -l filewc -w filewc -c file&: 计算文件行数计算文件中的单词数计算文件中的字符数

  cp sourcefile destfile&: 文件拷贝

  mv oldname newname : 重命名文件或移动文件

  rm file&: 删除文件

  grep 'pattern' file&: 在文件内搜索字符串比如:grep 'searchstring' file.txt

  cut -b colnum file&: 指定欲显示的文件内容范围,并将它们输出到标准输出设备比如:输出每行第5个到第9个字符cut -b5-9 file.txt千万不要和cat命令混淆,这是两个完全不同的命令

  cat file.txt: 输出文件内容到标准输出设备(屏幕)上

  file somefile&: 得到文件类型

  read var: 提示用户输入,并将输入赋值给变量

  sort file.txt: 对file.txt文件中的行进行排序

  uniq: 删除文本文件中出现的行列比如: sort file.txt | uniq

  expr: 进行数学运算Example: add 2 and 3expr 2 "+" 3

  find: 搜索文件比如:根据文件名搜索find . -name filename -print

  tee: 将数据输出到标准输出设备(屏幕) 和文件比如:somecommand | tee outfile

  basename file&: 返回不包含路径的文件名比如: basename /bin/tux将返回 tux

  dirname file&: 返回文件所在路径比如:dirname /bin/tux将返回 /bin

  head file&: 打印文本文件开头几行

  tail file : 打印文本文件末尾几行

  sed: Sed是一个基本的查找替换程序。可以从标准输入(比如命令管道)读入文本,并将结果输出到标准输出(屏幕)。该命令采用正则表达式(见参考)进行搜索。不要和shell中的通配符相混淆。比如:将linuxfocus 替换为 LinuxFocus :cat text.file | sed 's/linuxfocus/LinuxFocus /' > newtext.file

  awk: awk 用来从文本文件中提取字段。缺省地,字段分割符是空格,可以使用-F 指定其他分割符。cat file.txt | awk -F, '{print $1 "," $3 }'这里我们使用,作为字段分割符,同时打印第一个和第三个字段。如果该文件内容如下: Adam Bor, 34, IndiaKerry Miller, 22, USA命令输出结果为:Adam Bor, IndiaKerry Miller, USA

  2) 概念: 管道, 重定向和 backtick

  这些不是系统命令,但是他们真的很重要。

  管道 (|) 将一个命令的输出作为另外一个命令的输入。
  grep "hello" file.txt | wc -l
  在file.txt中搜索包含有"hello"的行并计算其行数。
  在这里grep命令的输出作为wc命令的输入。当然您可以使用多个命令。

  重定向:将命令的结果输出到文件,而不是标准输出(屏幕)。
  > 写入文件并覆盖旧文件
  >> 加到文件的尾部,保留旧文件内容。

  反短斜线
  使用反短斜线可以将一个命令的输出作为另外一个命令的一个命令行参数。
  命令:
  find . -mtime -1 -type f -print
  用来查找过去24小时(-mtime -2则表示过去48小时)内修改过的文件。如果您想将所有查找到的文件打一个包,则可以使用以下脚本:
  #!/bin/sh
  # The ticks are backticks (`) not normal quotes ('):
  tar -zcvf lastmod.tar.gz `find . -mtime -1 -type f -print`

  3) 流程控制

  "if" 表达式 如果条件为真则执行then后面的部分:
  if ....; then
    ....
  elif ....; then
    ....
  else
    ....
  fi
  大多数情况下,可以使用测试命令来对条件进行测试。比如可以比较字符串、判断文件是否存在及是否可读等等...
  通常用" [ ] "来表示条件测试。注意这里的空格很重要。要确保方括号的空格。
  [ -f "somefile" ] :判断是否是一个文件
  [ -x "/bin/ls" ] :判断/bin/ls是否存在并有可执行权限
  [ -n "$var" ] :判断$var变量是否有值
  [ "$a" = "$b" ] :判断$a和$b是否相等

  执行man test可以查看所有测试表达式可以比较和判断的类型。
  直接执行以下脚本:
  #!/bin/sh
  if [ "$SHELL" = "/bin/bash" ]; then
    echo "your login shell is the bash (bourne again shell)"
  else
    echo "your login shell is not bash but $SHELL"
  fi
  变量$SHELL包含了登录shell的名称,我们和/bin/bash进行了比较。

  快捷操作符

  熟悉C语言的朋友可能会很喜欢下面的表达式:

  [ -f "/etc/shadow" ] && echo "This computer uses shadow passwors"

  这里 && 就是一个快捷操作符,如果左边的表达式为真则执行右边的语句。您也可以认为是逻辑运算中的与操作。上例中表示如果/etc /shadow文件存在则打印" This computer uses shadow passwors"。同样或操作(||)在shell编程中也是可用的。这里有个例子:

#!/bin/sh
mailfolder=/var/spool/mail/james
[ -r "$mailfolder" ]' '{ echo "Can not read $mailfolder" exit 1; }
echo "$mailfolder has mail from:"
grep "^From " $mailfolder

  该脚本首先判断mailfolder是否可读。如果可读则打印该文件中的"From" 一行。如果不可读则或操作生效,打印错误信息后脚本退出。这里有个问题,那就是我们必须有两个命令:

  -打印错误信息
  -退出程序

  我们使用花括号以匿名函数的形式将两个命令放到一起作为一个命令使用。一般函数将在下文提及。
  不用与和或操作符,我们也可以用if表达式作任何事情,但是使用与或操作符会更便利很多。

  case表达式可以用来匹配一个给定的字符串,而不是数字。

case ... in
...) do something here
esac

  让我们看一个例子。 file命令可以辨别出一个给定文件的文件类型,比如:

file lf.gz

  这将返回:

lf.gz: gzip compressed data, deflated, original filename,
last modified: Mon Aug 27 23:09:18 2001, os: Unix

我们利用这一点写了一个叫做smartzip的脚本,该脚本可以自动解压bzip2, gzip 和zip 类型的压缩文件:

#!/bin/sh
ftype=`file "$1"`
case "$ftype" in
"$1: Zip archive"*)
  unzip "$1"
"$1: gzip compressed"*)
  gunzip "$1"
"$1: bzip2 compressed"*)
  bunzip2 "$1"
*) error "File $1 can not be uncompressed with smartzip";;
esac

  您可能注意到我们在这里使用了一个特殊的变量$1。该变量包含了传递给该程序的第一个参数值。也就是说,当我们运行:

smartzip articles.zip
$1 就是字符串 articles.zip

  select 表达式是一种bash的扩展应用,尤其擅长于交互式使用。用户可以从一组不同的值中进行选择。

select var in ... do
 break
done
.... now $var can be used ....

下面是一个例子:

#!/bin/sh
echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do
    break
done
echo "You have selected $var"

下面是该脚本运行的结果:

What is your favourite OS?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#? 1
You have selected Linux

您也可以在shell中使用如下的loop表达式:

while ...; do
....
done

while- loop 将运行直到表达式测试为真。 will run while the expression that we test for is true. 关键字"break" 用来跳出循环。而关键字"continue"用来不执行余下的部分而直接跳到下一个循环。

for-loop表达式查看一个字符串列表 (字符串用空格分隔) 然后将其赋给一个变量:

for var in ....; do
 ....
done

在下面的例子中,将分别打印ABC到屏幕上:

#!/bin/sh
for var in A B C do
 echo "var is $var"
done

下面是一个更为有用的脚本showrpm,其功能是打印一些RPM包的统计信息:

#!/bin/sh
# list a content summary of a number of RPM packages
# USAGE: showrpm rpmfile1 rpmfile2 ...
# EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpm
for rpmpackage in $*; do
 if [ -r "$rpmpackage" ];then
  echo "=============== $rpmpackage =============="
  rpm -qi -p $rpmpackage
 else
  echo "ERROR: cannot read file $rpmpackage"
 fi
done

这里出现了第二个特殊的变量$*,该变量包含了所有输入的命令行参数值。如果您运行showrpm openssh.rpm w3m.rpm webgrep.rpm
此时 $* 包含了 3 个字符串,即openssh.rpm, w3m.rpm and webgrep.rpm.


引号

在向程序传递任何参数之前,程序会扩展通配符和变量。这里所谓扩展的意思是程序会把通配符(比如*)替换成合适的文件名,它变量替换成变量值。为了防止程序作这种替换,您可以使用引号:让我们来看一个例子,假设在当前目录下有一些文件,两个jpg文件, mail.jpg 和tux.jpg。

#!/bin/sh
echo *.jpg
这将打印出"mail.jpg tux.jpg"的结果。
引号 (单引号和双引号) 将防止这种通配符扩展:
#!/bin/sh
echo "*.jpg"
echo '*.jpg'
这将打印"*.jpg" 两次。

单引号更严格一些。它可以防止任何变量扩展。双引号可以防止通配符扩展但允许变量扩展。

#!/bin/sh
echo $SHELL
echo "$SHELL"
echo '$SHELL'

运行结果为:
/bin/bash
/bin/bash
$SHELL

最后,还有一种防止这种扩展的方法,那就是使用转义字符——反斜杆:

echo *.jpg
echo $SHELL
这将输出:
*.jpg
$SHELL
Here document.

当要将几行文字传递给一个命令时,here document.(译者注:目前还没有见到过对该词适合的翻译)一种不错的方法。对每个脚本写一段帮助性的文字是很有用的,此时如果我们四有那个here document.就不必用echo函数一行行输出。 一个 "Here document.quot; 以 << 开头,后面接上一个字符串,这个字符串还必须出现在here document.末尾。下面是一个例子,在该例子中,我们对多个文件进行重命名,并且使用here document.打印帮助: #!/bin/sh # we have less than 3 arguments. Print the help text: if [ $# -lt 3 ] then cat <<< shift by 2
  --) shift;break;; # end of options
  -*) echo "error: no such option $1. -h for help";exit 1;;
  *) break;;
esac
done

echo "opt_f is $opt_f"
echo "opt_l is $opt_l"
echo "first arg is $1"
echo "2nd arg is $2"

您可以这样运行该脚本:
cmdparser -l hello -f -- -somefile1 somefile2

返回的结果是:
opt_f is 1
opt_l is hello
first arg is -somefile1
2nd arg is somefile2

  这个脚本是如何工作的呢?脚本首先在所有输入命令行参数中进行循环,将输入参数与case表达式进行比较,如果匹配则设置一个变量并且移除该参数。根据unix系统的惯例,首先输入的应该是包含减号的参数。

  实例

  一般编程步骤

  现在我们来讨论编写一个脚本的一般步骤。任何优秀的脚本都应该具有帮助和输入参数。并且写一个伪脚本(framework.sh),该脚本包含了大多数脚本都需要的框架结构,是一个非常不错的主意。这时候,在写一个新的脚本时我们只需要执行一下copy命令:
cp framework.sh myscript
然后再插入自己的函数。

  让我们再看两个例子:

  二进制到十进制的转换

  脚本 b2d 将二进制数 (比如 1101) 转换为相应的十进制数。这也是一个用expr命令进行数学运算的例子:

#!/bin/sh
# vim: set sw=4 ts=4 et:
help()
{
 cat << 'xixihehehaha',

在ubuntu下安装bugzilla

Convention:
$APACHE_HOME : installation directory of apache server.
$BUGZILLA_HOME : installation directory of bugzilla.
$MYSQL_HOME : installation directory of mysql.

Prerequirement:
Bugzilla : 2.22 release (2.22)
Perl : 5.6.1 or higher (5.8.7)
Mysql : 4.0.14 or higher (5.0.21)
Apache : 1.3 or 2.x (2.2.2)
Ubuntu : 6.0.6
GCC: apt-get install build-essential

Detailed steps:
===============================
Apache Intallation
===============================
I don't know if apache has been built in my ubuntu, so reinstalling apache is maybe a good idea. The distribution of apache for linux must be built from source.
1. download httpd.apache.org, I chose the latest stable release httpd-2.2.2.tar.gz.
2. extract source package
Here you should check if your ubuntu has insalled build environment, if not, install it by executing 'sudo apt-get install build-essential'.
3. build the source code, and do installation.
- ./configure --prefix=$TARGET_DIR
- make
- make install
4. enter $APACHE_HOME/bin, execute './httpd -k start' or './apachectl start' to start apache server. After that, open browser and access 'http://localhost' to check if server has been startup.

===============================
Mysql Intallation
===============================
It seems like that the installation of mysql is really simple. I just downloaded the binary package from www.mysql.com, then extract it to a directory. Don't need to compile, dont need to install. Enter mysql root directory, execute './configure', then it is ok.
You can start mysql daemon server by executing './bin/mysqld-safe'.
Do remember that this is justa short cut, it need a more speculated configuration in a product environment, such as creating user account, security configuration.
DO MORE RESEARCH!!

创建一个bugzilla账户, 登陆到mysql
> grant all on bugs.* to bugs@localhost identified by 'bugs';
>flush privileges;

===============================
Install Perl Modules
===============================
Bugzilla need some special perl modules to support it behaviour.
1. enter $BUGZILLA_HOME, execute './checkperl.pl --check-modules'. check the output, you will get a list of uninstalled modules.
2. install depended modules. you can install by MCPAN(???) or download module from www.cpan.org and then install it from local machine.
2.1 install from remote : /usr/bin/perl -MCPAN -e 'install "XML::Twig"'
2.2 install from local:
- download module packege from www.cpan.org.
- extract the package, and enter the module directory.
- 'perl Makefile.pl', build a makefe file.
---------------------------------------------------
NOTE: 这一步可以指定一个参数PREFIX来设置将这个模块安装到什么地方,比如"perl Makefile.PK PREFIX=/opt/mylib/perl",那么'make install'时候,模块会被安装到/opt/mylib/perl,在这个目录下会被创建很多子目录,一般是:
/opt/mylib/perl/bin
/opt/mylib/perl/share
/opt/mylib/perl/share/perl/5.8.7 [这个目录下面放置模块文件]
/opt/mylib/perl/lib/perl/5.8.7 [这个目录下面也可以放置模块文件]
/opt/mylib/perl/man [帮助文档]

PERL 解释器搜索模块的路径可以通过一个变量来设置,PERLLIB,PERL5LIB两个变量都可以增加PERL解释器的搜索路径,最好两个变量都设置最保险,因为工具可能查找不同的变量,比如[export PERLLIB=/opt/mylib/perl/share/perl/5.8.7:/opt/mylib/perl/lib/perl/5.8.7], 多个目录可以用冒号分开。当然PERL总是会搜索默认的/usr/lib这个目录。
还有@INC不知道是什么东西。。。。。。(就象java的classpath环境变量)
---------------------------------------------------
- 'make' : build the source.
- 'make test' : do test
- 'make install' : install module
NOTE : when installed DBD:mysql moudle, you should specify some arguments. The first is 'cflags'(This is a list of flags that you want to give to the C compiler. The most important flag is the location of the MySQL header files.), second is 'libs'(his is a list of flags that you want to give to the linker or loader.The most important flags are the locations and names of additional libraries. ), such as 'perl Makefile.PL --cflags=-I<$MYSQL_HOME/include> --libs=-L<$MYSQL_HOME/libs>, also you can specify some other arguments, like testdb, testhost and so forth. Here will give a concrete example:
perl Makefile.PL --cflags="-I/opt/mysql/include" --libs="-L/opt/mysql/libs" --testdb=bugs --testuser=bugs --testpassword=bugs --testhost=localhost

后来的一次安装比较奇怪,我用[ perl Makefile.PL --cflags="-I/opt/software/mysql-max-5.0.21-linux-i686-glibc23/include" --libs="-L/opt/software/mysql-max-5.0.21-linux-i686-glibc23/lib" --testdb=bugs --testuser=bugs --testpassword=bugs --testhost=localhost ]这个指令创建Makefile,然后‘make, make test',在‘make test'的时候总是会报错:
-------------------------------------------------
t/40nulls............install_driver(mysql) failed: Can't load '/opt/source/perl-bugzilla-modules/DBD-mysql-3.0006/blib/arch/auto/DBD/mysql/mysql.so' for module DBD::mysql: /opt/source/perl-bugzilla-modules/DBD-mysql-3.0006/blib/arch/auto/DBD/mysql/mysql.so: undefined symbol: mysql_stmt_free_result at /usr/lib/perl/5.8/DynaLoader.pm line 225.
-------------------------------------------------
而我第一次和第二次安装的时候都没有问题,也是perl5.8.7和DBD::mysql3.0006,为什么?? 没有办法,去网上查了一个,好多人问这个问题,而且这个bug看来是新版本里面才出现的, 总算也有人给出了解决方法,就是用下面的指令:
perl Makefile.PL --cflags="-I/opt/software/mysql-max-5.0.21-linux-i686-glibc23/include" --libs="-static-libgcc -L/opt/software/mysql-max-5.0.21-linux-i686-glibc23/lib -lmysqlclient -lz -lposix4 -lgen -lsocket -lnsl -lm" --testdb=bugs --testuser=bugs --testpassword=bugs --testhost=localhost
唉,终于‘make test'通过了,不简单,值得庆贺。
--------------------------------------------------
笑的太早啦,现在我第三次在ubuntu上面安装,这个DBD::mysql模块又好好的折腾了我一把,差点让我疯掉了,难道每次安装都要碰到那么多新问题么? 就说说这次的经历吧, mysql仍然是自己从mysql网站下载了一个二进制包,然后在ubuntu下安装的。就是说完全按照第二次的安装经验,一开始就碰到了一个异常,我直接把cpan上的解决描述贴在这里:

Some Linux distributions don't come with a gzip library by default. Running ``make'' terminates with an error message like

  LD_RUN_PATH="/usr/lib/mysql:/lib:/usr/lib" gcc
-o blib/arch/auto/DBD/mysql/mysql.so -shared
-L/usr/local/lib dbdimp.o mysql.o -L/usr/lib/mysql
-lmysqlclient -lm -L/usr/lib/gcc-lib/i386-redhat-linux/2.96
-lgcc -lz
/usr/bin/ld: cannot find -lz
collect2: ld returned 1 exit status
make: *** [blib/arch/auto/DBD/mysql/mysql.so] Error 1

If this is the case for you, install an RPM archive like libz-devel, libgz-devel, zlib-devel or gzlib-devel or something similar.

解决办法就是安装zlib: sudo apt-get install zlib1g-dev.
接下来碰到的问题更恼火,在"make test"的时候,得到下面的异常:

  t/00base............install_driver(mysql) failed: Can't load
'../blib/arch/auto/DBD/mysql/mysql.so' for module DBD::mysql:
../blib/arch/auto/DBD/mysql/mysql.so: undefined symbol: _umoddi3
at /usr/local/perl-5.005/lib/5.005/i586-linux-thread/DynaLoader.pm
line 168.

原因据说是因为编译perl的编译器与编译mysql的编译器不一样,或者他们编译的目标平台不一样,就会出现这个问题,cpan也提供了解决方案,我试了,没用,可以参考这里:

http://search.cpan.org/src/CAPTTOFU/DBD-mysql-4.003/INSTALL.html#configuration

疯了,越安装反而越搞不定了, 后来没办法,我决定删除自己的下载的mysql,通过apt-get来安装,这样的话因为perl和mysql都是ubuntu自己,应该不会有问题了吧!

>sudo apt-get install mysql-server
>sudo apt-get install libmysqlclient14
note: 必须安装mysqlclient,才能得到mysql_config,这个文件定义了编译器需要的各种flag。

然后再来执行 “perl Makefile.PL --mysql_config=/usr/bin/mysql_config --testdb=bugs --testuser=bugs --testpassword=bugs --testhost=localhost“
哈哈,这下make test终于成功了。

** 安装GD库
> wget http://www.libgd.org/releases/gd-2.0.34.tar.gz
> ./configure;
> make
> make install
安装其他的库(依赖于GD)
> perl -MCPAN -e 'install "Chart::Base"'


** 我看最好的安装perl module的方式应该是先安装zlib,gdlib,DBD::mysql这些之后,使用”perl -MCPAN -e 'install "Bundle::Bugzilla",不然真是很麻烦。

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

You can view these arguments by adding '--help' following the command.
More information please refer to the installation document of module.
3. After complete installing depented modules, you should rerun './checksetup.pl' (no '--check-modules' argument). This command will generate a configuration file 'localconfig', and build database structure(Confirm that all configuration about database is correct, you need create db_user. The script will generate schema automatically.).这里需要手工修改localconfig文件,设置数据库连接等。我通常还会把webservergroup设置成登录账户,管不了那么多, linux的安全设置搞的我很烦,只要能让bugzilla跑起来,管不了了。
4.完成配置之后,再运行checksetup.pl,脚本会自动创建数据库。
5. Config apache for bugzilla. I adopted a very extreme approach which just copy all files in $BUGZILLA_HOME to $APACHE_HOME/htdocs, then add below block to httpd.conf:

note: 在localconfig中设定webservergroup为www-data,并且重新执行checksetup.pl。 设置$BUGZILLA_HOME的owner为www-data。
??不知道为什么直接加符号链接的时候,apache会直接显示perl源文件。

Optional: If Bugzilla does not actually reside in the webspace directory, but instead has been symbolically linked there, you will need to add the following to the Options line of the Bugzilla directive (the same one as in the step above):

 +FollowSymLinks
note: Options +Indexes +ExecCGI +FollowSymLinks

NOTE : By default the DocumentRoot directory of apache is $APACHE_HOME/htdocs, but I want put my web application outside DocumentRoot directory. How do I achieve that? It is simple, just create a symbol link in DocumentRoot directory for you application directory. For example:
- change directory to $APACHE_HOME/htdocs(the DocumentRoot directory).
- 'ln -s /opt/bugzilla-2.22 bugzilla'.
Then you can access 'http://localhost:8080/bugzilla'.
6. Start apache and bugzilla. Access 'http://localhost:8080', now the bugzilla index page is displayed.
THIS IS JUST A BEGIN.

NOTE: All bugzilla parameter settings are stored in ${BUGZILLA_HOME}/data/params.

自己动手装bugzilla,在ubuntu下面。

我的电脑现在是双系统, 一个ubuntu,一个windowXP. 本来都已经计划以后只使用ubuntu的, 但是现实情况很难, 公司里的工作都是在window平台上, 很受不了, 全是盗版, 而且主要的公司的产品完全是跑在window平台上的。 当然我平常工作使用ubuntu并非不可能, 但是太麻烦, 而且公司的版本控制使用的是vss, 这个丑陋的东西没有linux下的客户端, 还有inforweb也没有linux的版本, 所以我现在实际上大多数时间使用的都是window。
有 一点, 在我的项目組内,肯定会有一个linux服务器, 版本管理会回到cvs,而bugzilla也将在开发过程中扮演重要角色, 现在公司内部根本就没有缺陷管理系统,不是一般的糟糕。 后面的,我还计划建立一个项目的内部协作网络, 其实作用倒可以很多,也可以是内部知识网络,项目的管理也可以通过这个系统来进行。 这个会通过twiki来实现, 正好twiki和bugzilla都是基于perl的, 不用整那么多新东西了。

今天就打算装个bugzilla, bugzilla实际上是很多开源技术的一个整合, 清单如下:
Bugzilla : 2.22 release
Perl : 5.6.1 or higher
Mysql : 4.0.14 or higher
Apache : 1.3 or 2.x (2.2.2)
Ubuntu : 6.0.6

由于ubuntu内置了perl,所以不用安装.
-- 安装apache.
从www.apache.org下载了2.2.2版本的, 但是在linux下面, 必须要从源代码开始编译。
1。检查ubuntu是否已安装了开发环境。
- 查询是否已经安装了build-essential包。
- 如果没有, 那么‘sudo apt-get build-essential', 这个命令会自动安装gcc等相应的资源。
2。解开httpd-2.2.2.tar.gz, 进入httpd-2.2.2,执行‘./configure --prefix=$PREFIX'。通过指定prefix参数, 可以指定将apache安装到一个特定目录。
3。执行 ‘make', 编译源代码。
4。执行‘make install‘, 执行安装过程。
5。进入$PREFIX/bin, 执行‘./apachectl start’启动apache,然后在浏览器里面访问‘http://localhost',就可以看到服务是否启动成功了。

-- 安装mysql
mysql-5.0.21的安装好像很简单, 不过这是初步的认识, 因为直接运行'./bin/mysqld_safe'就可以启动mysql的服务。下面列出一些常用命令:
mysqladmin version : view the version information.
mysqladmin shutdown: shutdown mysql daemon server.
mysql -u root -p : login mysql and a password prompt will be displayed.

Wednesday, June 28, 2006

关于软件研发:一个愚蠢农夫和奶牛的故事

Ivar Jacobson博士他被认为是影响或改变了整个软件工业开发模式的几位世界级大师之一,是软件方法论的一面”旗帜”。他是组件和组件架构、用例、现代业务工程、Rational统一过程等业界主流方法或技术的创始人。
  
Ivar Jacobson博士认为,如果采用不良的软件过程,通过CMM/CMMI的成熟度级别越高,只会使软件企业生产不合格软件的过程更加有效率,而不是使企业开发出更好的软件。
  
软 件外包是时下的一个热门话题,被我国不少软件企业视为一座金矿,而CMM被人们认为是进入这个市场的敲门砖,为了拿到那张代表资格的CMM认证证书,不少 企业甚至不惜投入数百万之巨。事实上,拿到CMM认证在国外并不代表企业就能提供一个合格的软件,著名的软件专家、拥有组件技术、用例技术等多项发明、与 Grady Booch、James Rumbaugh一起被称为UML之父的Ivar Jacobson博士在近期访华期间一再提醒中国的软件企业,谨防掉入CMM陷阱。

CMM/CMMI的缺点
  
CMM/CMMI最早起源于美国国防部。为了改变在采购过程中频繁地采购到大量不合格软件的局面,美国国防部需要一种评估软件质量的方法,这就是要求软件企业进行CMM/CMMI认证。然而,CMM/CMMI真正解决这个问题了吗?
  
CMM/CMMI 被认为是一种最成熟、最有效地提高软件工程化水平的方法和标准,用来评估和改进过程,它是一个描述在软件开发过程中有待改进的关键因素的框架,描述了一个 能用渐进方式进行改进的途径。它为软件过程改进提供一个基础,将软件开发从一个相对来说随意、不成熟的过程变成非常成熟的、有规律的、可管理的过程。
  
然 而,CMM/CMMI也有一些与身俱来的缺点不容忽视。比如,CMM/CMMI的评估耗资不菲,一个CMM2级评估就可能达到数百万之巨,而且耗时很长, 过程十分复杂,常常导致效果不太理想。不少企业的认证流于形式,评估完成后就只留下一大堆文档,而真正的软件开发过程却依然故我。而且,CMM/CMMI只告诉我们应该怎么做,而没有具体地告诉如何做。比如说,它要求必须改进需求管理,那么到底该如何做需求管理?CMM/CMMI没有提供答案。
  
还有最重要的一点是,不少软件企业陷入了一个误区,以为单单通过CMM/CMMI评估就可以解决软件质量不高的问题,而忽略了软件过程这一真正改善软件质量的环节。 事实上,完全有可能出现这样的情况: 软件成熟度为CMM 1级或2级的企业开发出的软件是真正好用的,而有的企业即使通过了CMM 5级认证,也无法保证它交付好的软件。最糟糕的情形是,如果采用不好的软件过程,通过CMM/CMMI的成熟度级别越高,只会使软件企业生产差劲软件的过 程变得更加有效率,而不是使企业开发出更好的软件。

Ivar Jacobson认为,好的软件过程首先一定是基于组件的,在此基础之上,还要符合迭代开发、用例驱动开发和以架构为中心的这三个最佳实践。

理的软件过程是软件质量的基础
  
为 什么会是这样呢,Ivar Jacobson举了一个非常形象的例子。这是一个农夫和他的奶牛的故事。在奶牛喝水的途中(称为”牛路”)有一片庄稼地,牛会吃掉很多庄稼。农夫看到这 种情况后,意识到必须对奶牛喝水的过程进行改进,所以他就在这条道路上铺上了沥青。结果,农夫得到了一个好的”牛路”,牛走得更快了,但是并没有真正解决 牛吃庄稼的问题。它应该有更好的方式,就是为牛喝水寻找一条全新的道路。

软件企业利用 CMM框架进行软件质量控制的过程,就像是这个农夫为牛路铺沥青。对于软件企业来说,如果从一个错误的软件过程开始,即使你在这个上面再改进,得到的永远 只是”牛路”。这里更应该考虑的是要选择一条更好的路,也就是从一开始时,就采用能够开发出好的软件的过程。然后在这个软件过程的基础上,对这个软件进行 度量,改进这个软件的过程,也就是进行CMM/CMMI要求的改进。

Ivar Jacobson博士认为,从一个不良的软件过程出发,在此基础上进行改进,实际上会把软件开发变得更糟糕,因为你把软件开发过程固化了,使日后再想对它进行改造,变得更加困难。正确的方法是,先要有一个好的软件过程,这是不容易的,但是值得做的事情。
?
Ivar Jacobson 说,”把一个好的软件过程变得可度量非常容易,但是把一个可度量的软件过程变成一个好的软件过程却很难。也就是说,只有把一个好的软件过程,即能够开发出好的软件的过程变得可度量才是有益的。而把一个已经经过CMMI改进的、可度量的过程变成一个真正的能够开发出好软件的过程,这是几乎不可能的事情。

那么什么是一个好的软件过程?Ivar Jacobson建议从以下几个方面进行辨别:
1 坏的过程关注文档上,而好的过程关注在可执行的程序或者系统上;
2 坏的过程延误了揭露风险的时间,而好的过程一开始就把自己暴露在风险之下,并及时解决它;
3 坏的过程在项目的最后才能够验证这个项目的质量,而好的过程其质量是每时每刻都能够得到验证的;
4 坏的过程有一个非常复杂的跟踪关系矩阵,从需求到代码需要一个非常复杂的矩阵,而好的过程,却是一个无缝链接;
5 在面对变更时,坏的软件很脆弱,好的软件会很健壮。
  
Ivar Jacobson提醒软件开发人员要做聪明的农夫,首先得到一个正确的软件过程; 然后,再考虑去度量它、定义它。因为软件项目管理的本质不是能否描述并度量软件过程以及过程到底怎么样,而是首先关注软件,你是否能很好地开发出合格软 件。重点是得到结果,通过软件过程得到这个结果,也就是交付的软件产品。

观点碰撞
敏捷开发企图终结软件危机
  
如 今在软件开发领域占绝对主流地位的传统软件工程学思想是大约在20世纪60年代伴随着”软件危机”言论的出现而诞生的。所谓软件危机是指在计算机软件的开 发和维护过程中所遇到的一系列严重问题,它包含两方面内容:一是如何开发软件,以满足不断增长、日趋复杂的需求;二是如何维护数量不断膨胀的软件产品。的 确,传统软件工程学思想的诞生,把软件开发活动按照工程化的原则和方法进行组织,并一度被认为是摆脱软件危机的一个主要出路。
  
但 是,数十年后的今天,人们对于软件危机的”恐惧”仍没有丝毫减弱,相反随着软件系统的急速膨胀而越发不可收拾了:对软件开发成本和进度的估计常常不准确, 开发成本超出预算,实际进度比预定计划一再拖延的现象并不罕见;用户对”已完成”系统不满意的现象也经常发生;软件产品的质量往往靠不住,Bug一大堆, 补丁一个接一个;等等。于是,无论是产业界还是理论界,都开始对传统软件工程学思想产生怀疑,甚至背叛。因此,关于软件到底是”工程”还是”艺术”的讨论 一度风靡全球。而以迭代式循序渐进开发方式为主,以”人”为核心的敏捷开发方法就是在这样的背景下产生的,它背叛了传统软件工程学中以”过程”为核心,把 设计和开发尽可能分开,尽量弱化”人”在整个工程中地位的思想。
  
近日,当世界软件开发领域最具影响力的五位大师之一、 敏捷软件开发方法的早期开拓者马丁·福勒先生来华与国内软件高手论道之际,北京大学软件学院院长阵钟老师再次将软件是”工程”还是”艺术”这一问题摆到了 桌面上。而这位软件教父似乎对这一问题早有深入思考,他认为,这一争论的核心应该在于软件设计是否要与软件开发分开,这也正是传统工程化软件开发方法与敏捷软件开发方法的重要区别。
  
作为敏捷软件开发方法的推动者,马丁先生认为,软件设计应该和软件开发紧密结合在一起,采用迭代式开发。软件开发不能被认为是一个既定的过程,因为软件开发中有太多的变化出现,既定的过程设置不可能达到合适的预想结果由于需求变化、技术更新、人员流动等问题的存在,许多软件设计工作应该在软件开发到一定程度的时候才能进行,两者不应该在顺序上严格分开。他说:”至于从 哲学的角度讲,到底软件开发活动是艺术还是工程呢?我很难清晰地界定,也许都是或者都不是。也许我们应该把软件开发活动当做一个独立的东西来对待。”
  
由 此看来,马丁先生既不认为软件开发活动应该是一个先进行设计,然后根据 “设计图纸”进行构建的工程化过程,也不认为软件开发应该是完全依赖于开发者头脑中随时蹦出的灵感的艺术活动,因为这两种倾向在人类数十年的软件开发实践 中已经被证明都不甚完美。而他企图在两者之间找到一个均衡点,这个均衡点也许正是真正解决”软件危机”的突破口。
  
据了 解,敏捷开发实际上包括了许多优秀的软件开发习惯。首先,这种方法改变了软件测试的流程,在编写代码前进行测试,减少了开发风险;其次,可以对软件进行持 续集成,即每个小时都在集成,任何部件间的冲突都可以随时解决;此外,这种方法的”动态规划”和”重构”做法,意味着开发者可以对软件架构进行持续改进, 可以根据用户的需求随时进行改进,而利用传统的软件开发方法则很难对软件的架构进行调整,同时也会造成成本的大幅增加。