分类: IT生活

用编译器编译编译器

这是一个很有意思的话题,思考过后,特此记录。

我用Gentoo第一次升级GCC的时候,以为系统会下载一个二进制包来替代现有的GCC,结果却发现:系统用旧版本的GCC编译来编译新版本的GCC!GCC是什么语言写的?去查了查,真的是C语言。现在一个有趣的问题就出现了:GCC是一个C语言编译器,它本身就是用C语言写的,请问怎么编译GCC?

答案很简单:用旧版本的GCC编译新版本的GCC。但是世界上第一个GCC是怎么编译的?用其它C语言编译器编译出来的。世界上第一个C语言编译器是怎么编译出来?是用其它语言编写的……世界上第一个编译器是怎么来的?恐怕就是用机器语言写的吧。

比尔盖子又想到第二个问题。如果一个C语言编译器是用其它编译器编译出来的,那它本身的机器代码就和自己无关,和那个编译它的编译器有关了;如果一个编译器试图扩展C语言,那它本身也不能使用自己所支持的扩展特性了。因此,我们需要先用不包括扩展特性的语法先得到一个这个编译器的二进制版本,然后再用它来编译包括扩展特性的编译器代码,然后用编译器再编译它自身才行。

P.S:其实GCC的第一个版本是用Pascal写的。

Apache 之 mod_status 配置问题解决(403, 404错误)

为了使用监控宝来监控比尔盖子Apache的运行状态,比尔盖子打算启用mod_status模块来访问biergaizi.com/server-status页面。

结果,屡次失败。后来干脆把安全严重去掉,直接将以下配置添加到/etc/apache2/httpd.conf中,也根本不管用,永远提示403错误:

ExtendedStatus On
<Location /server-status>
    SetHandler server-status
    Order deny,allow
    Allow from all
</Location>

难道是这个模块有专门的配置文件被引用,从而覆盖了盖子的设置?经过长期奋战,终于最后通过文本流搜索,找到了/etc/apache2/mods-enabled/status.conf文件:

    SetHandler server-status
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1 ::1

原来只允许127.0.0.1,难怪无法访问。但是去掉这个安全规则之后,确实再也不提示403了,反而变成盖子博客的404页面了。难道是和虚拟主机的配置冲突?经过搜索,发现确实如此。解决之一是将Virtualhost中所有的*:80都变成具体的IP地址,但是这个规则是控制面板管理的,还是不动为好;或者为/server-status专门指定一个监听端口,直接在前面加上Listen 8050之类的端口就行了。

最后的规则如下:

#专门监听2500端口
Listen 2500
ExtendedStatus On

SetHandler server-status
Order deny,allow
Deny from all
#只允许监控宝
Allow from 60.195.252.106

当然,不要尝试访问http://biergaizi.com:2500/server-status/页面,你连403页面也看不见的——有iptables!想看看iptables规则?保密,稍后公布。

apt-get 导致硬盘爆满的解决之道

折腾完Ubuntu之后,硬盘空间迅速爆满。比尔盖子不得不几次停下VPS,进行扩容操作。导致是什么鬼东西耗尽了我的硬盘。一气之下,使用

du -sh /*

进行检查。结果如下:

12K		/aquota.group
8.0K	/aquota.user
7.9M	/bin
34M	/boot
4.0K	/dev
13M	/etc
985M	/home
0	        /initrd.img
188M	/lib
16K	        /lost+found
32K	        /Maildir
8.0K	/media
12K	        /mnt
4.0K	/opt
0	        /proc
160K	/root
216K	/run
6.2M	/sbin
4.0K	/selinux
12K		/srv
0		/sys
8.0K	/tmp
1019M	/usr
1.3G	/var
0		/vmlinuz

怎么?/var占了这么多空间,难道是日志太多吗?继续输入

du -sh /var/*

进行检查:

736K	/var/backups
488M	/var/cache
16K		/var/crash
697M	/var/lib
4.0K	/var/local
0		/var/lock
41M	/var/log
4.0K	/var/mail
4.0K	/var/opt
0		/var/run
772K	/var/spool
4.0K	/var/tmp
16K		/var/usermin
4.0K	/var/virtualmin-autoreply
22M	/var/webmin
12K		/var/www

这么多缓存文件?都是些什么东西?再看:

du -sh /var/cache/*
8.0K	/var/cache/apache2
401M	/var/cache/apt
15M	/var/cache/apt-show-versions
67M	/var/cache/apt-xapian-index
4.0K	/var/cache/awstats
12K		/var/cache/bind
4.4M	/var/cache/debconf
20K		/var/cache/ldconfig
1.6M	/var/cache/man
8.0K	/var/cache/postgresql
4.0K	/var/cache/pppconfig

进入/var/cache/apt一看,原来是里面有个叫archives的目录,存在大量apt-get下载过的软件包,难怪硬盘空间迅速变小。速速删除之,根目录果然多了大量空间!

rm -r /var/cache/apt/archives/*

切换VPS到Ubuntu

最近比尔盖子将服务器重新安装了操作系统。最开始使用Linode的时候,使用的操作系统是CentOS 6,但后来发现CentOS为了稳定性,实在也太保守了,很多软件甚至落后上游3、4个版本,比如Python,都2.6了,CentOS里面居然还是2.4!——一句话,除了安全更新,什么都不管!

为了追求性能,改用了Gentoo,同时也开始提供虚拟主机服务。但是几乎没有任何一种虚拟主机管理面板支持Gentoo!后来强行安装了Virtualmin/Webmin,勉强运行起来了。我自己还用Nginx替换了Apache;MariaDB替换了MySQL。也算是一个大实验吧。

这勉强运行起来的系统环境给比尔盖子造成了无穷的痛苦啊,比如,自动修改配置文件的功能根本无法工作,只能人工修改,简直就是一个半自动的系统环境——甚至不如手动编写配置文件。前天,终于下定决心,更换一个Virtualmin可以运行,但自己也能接受的Linux发行版。Debian,占用资源小,但也保守;正巧想到了Ubuntu。这个系统比尔盖子不是很喜欢,因为它把很多传统上需要Linux用户自己做的事情,都给自动化了——显示不出盖子的水平啊(其实是反而给盖子添乱)!而且这个系统据说用来做服务器也不是很稳定。

但是,看到很多搞云计算的都开始用,而且这个系统的最新版本12.04 LTS,可以支持VIrtualmin,便还是决定安装了。运行Virtualmin的安装脚本之后,什么都不用管,很快就装完了。而且这个管理面板安装这些软件的方式,居然不是编译安装,是调用apt-get安装,非常不错,

安装好管理面板后,恢复所有服务,折腾半天。恢复完之后,打算在Linode上运行Ubuntu官方内核,又折腾半天,成功运行了linux 3.2,但盖子想用3.4,于是增加软件源,直接从12.04 LTS切换到Development Branch,虽然不太靠谱了,但是对于盖子来说还是可以接受的,而且用上了linux 3.4的内核。

不过最要命的是,Virtualmin默认安装并配置启用了Mail Server、Bind、PostgreSQL等等根本用不到的东西,服务器的可用内存动不动就只剩下100M,Swap也常常出动……算了,最后优化吧。

Gentoo神秘而又气死人的RAID bug

昨天更新完Gentoo,重新启动机器后发现,Gentoo不认RAID了。又重启一下,这回不但依然不认,英特尔的芯片还告诉我:RAID已损坏,进入系统后将Rebuild⋯⋯我发现我的Fedora还能认阵列,马上进去Rebuild。Rebuild好了,发现每次进入Fedora没有任何问题,进入Gentoo就会这样。

后来进入Gentoo仔细研究,发现Gentoo把三块硬盘组成的RAID 5认成了两个阵列。Rebuild完之后,倒是能正确的认出来,但是由于之前造成数据不同步,导致Rebuild。经过搜索,发现这个Bug已经有所报告,是由于关机时没有正确停止RAID造成的,之前也遇到过,并自己解决。但是,我这样不认+阵列坏的问题,倒是离奇。

只能使用重装系统之大法了。

遭遇最坑爹的在线订餐——必胜宅急送

今天打算在http://www.4008123123.com(必胜宅急送)上订餐,结果发现Web页面加载不全,点确定就提示“请选择订餐时间”,可根本就没有这个选项。看来是浏览器兼容问题了,用IE、IE(兼容模式)、Chrome、Firefox狂试,最后用Linux Firefox浏览器,选项终于出现了……而奇怪的是Windows下的Firefox居然不行?上去之后选择要订的食物,点击提交的时候要么没有反应,要么就无限的“正在加载”。

看到网络用的是JSP——甲骨文的Java到底考不靠谱?试了10来次都是这样。最后发现网络页面加载残缺不全——会不会只是线路问题。打开SSH连接到比尔盖子位于日本东京的服务器,然后用端口转发做代理,居然成功了。原因看来就是线路问题,不过有两种可能:第一种情况是:比尔盖子使用双WAN路由器,很可能是负载均衡导致有两个IP发出请求导致服务器端判断错误——不过在HTTP上看少见到这种情况——只能说是判断策略不成熟;第二种情况就是联通线路问题了。

因此,双WAN路由器出现这种情况不妨先禁用负载均衡,如果太麻烦就每次有这种交易的时候打开代理或者VPN就可以了。

关于Vim&Emacs的中文分词相关讨论

在Vim中,基于单词的文本编辑命令是相当有用的。比如使用命令3dw即可删除三个单词。但是在中文中,由于存在相当烦人的分词问题,因此,也就无法实现这样的功能。

但情况远远比这更糟,vi设计之初就遵从的是KISS原则。标点符号和空格分词等,是写死的C代码中的,而Vim也是如此。反观Emacs,则是全部可以使用配置文件进行配置的。正是因为Emacs这种行事风格,也才导致了软件功能膨胀,不过确实提供了神一般的可定制性。

而关于中文分词,我的建议很简单:在Vim读入文件后使用外部工具进行分词,然后反馈给Vim插件,Vim插件检测用户光标的位置,并把cw、dw这样的键映射给插件。如果用户使用dw,那么就根据词语使用d3l来代替dw。

不过这样有一些需要讨论的地方:

1.分词的准确性问题
中文分词一直是一个难题,除了大规模数学统计的方法可以获得较准确的结果外,只能指望今后的人工智能了:( 如果是这样,Vim的分词将不会给用户带来方便,而是烦恼——一些莫名奇妙的词语发生了改变,而不是想要的结果。

2.“大词”和“小词”
拿一个常见的词语来举个例子:发展中国家。这个词语在分词不准确的情况下会分成:发展/中国/家,而在分词准确的情况下则能正确将“中”分出来。但问题是,“发展中国家”单独也成一词。用户在一些情况下可能会希望对“发展中国家”为单位进行操作,但有时仅仅希望删去“发展”一词。如何权衡就是一个很大的问题了。

3.“分词线”
为了避免不可预测的分词结果带来反而难以操作的后果,“分词线”是一个需要实现的功能。即,在每一个分成的汉语词中添加下划线或是斜杠等符号来将词语隔开。但是要在Vim中实现“所见即所得”式的排版效果来显示出“删除线”,恐怕是无法解决的一大问题了,而Emacs可能还好一些。

另外,我对汉语分词技术的一点幻想是“定义词”。假如文章中有这么一句话:“我把它叫做一个‘集合’”,那么分词程序可以根据语义,实时的定义新词。先显然,基本无法实现。另外,我对Vim中中文的折行、不停切换输入法,和不支持中文引号匹配导致前后引号混用的问题也有些意见。显然,Emacs里自带输入法模块,没有此问题。据说VimIM可以解决汉语和vi命令冲突的问题?

欢迎大家对以上问题进行交流。

比尔盖子

Fedora Linux下GVim无菜单、乱码的解决方法

有时,Linux系统安装完GVim后,你会发现它在UTF8中文环境下,无菜单和乱码。原来,GVim是根据系统LANG变量来检测语言并使用相应语言文件的。但是,对于中文,GVim只能识别zh_CN.utf-8,而不能识别不带“-”的zh_CN.utf8(晕)!

解决的方法很简单,到GVim的文件目录的lang目录下,比如/usr/share/vim/vim73/lang,然后做一个软链接(符号链接):

ln -s menu_zh_cn.utf-8.vim menu_zh_cn.utf8.vim

再打开GVim,你就会发现菜单正常了!

版权所有 © 2025 比尔盖子 博客

主题设计 Anders Noren返回顶部 ↑