2011年11月28日星期一

怒斥Ubuntu

先讲个故事。你闻到家里很臭,但是不知道臭味从哪里来的。最后发现是家里的保姆偷偷在墙角拉屎了。原来这位保姆有随地大小便的习惯。甚至在小区里面也喜欢随地大小便,不过小区被物业和所有业主盯着,所以保姆很少在小区干,而且拉完后自己会立刻清理掉。恶心吧?

其实这个保姆就是Ubuntu。

今天想在软件中心找个软件,考虑到英文界面下看到的评分和评论会比较多,就想把语言从中文切换回英文。可是在设置的语言支持里面改了之后,部分locale是en了,但有几个还是zh,设置语言的图标名称还是“语言支持”中文的,而不是Language Support。

试着修改/etc/default/locale,把~/.config移除,用了locale-gen --purge把其它locale都删除,还有localepurge软件,都无效。只好又在/etc下用grep -R zh_CN *来搜索了,发现/etc/environment文件里面赫然写着中文locale的环境变量:
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
LANGUAGE="zh_CN:en"
LANG="en_US.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_CTYPE="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
我把里面几个locale的环境变量都删除,还重启了电脑,仍然无效,上面几个locale设置还是有效。真是气愤这破玩意!

我又在家目录下用grep -R zh_CN `ls -A | grep '^\.'`搜索,愤然发现.profile的最后几行:
export LANG="en_US.UTF-8"
export LANGUAGE="zh_CN:en"
export LC_MESSAGES="zh_CN.UTF-8"
export LC_CTYPE="zh_CN.UTF-8"
export LC_COLLATE="zh_CN.UTF-8"
这几行删除掉后终于干净了。你妈的,都污染到.profile文件了。好吧,拉就拉吧,谁让你住我家呢,可是你他妈的能不能拉完了清理一下啊,害老子浪费一上午时间!我已经默念无数遍Fuck Ubuntu了。

/etc下面的配置文件,系统在软件安装、删除、升级的时候一般都会考虑到配置。而家目录下的设置,软件往往只管写,软件删除了这些配置也保留,当然这是对的,这是用户数据要一直留着;软件升级了也不会对应升级,如果配置文件不兼容了那就会出问题。

Ubuntu把设置直接写到.profile这么关键的文件中,而且又是locale这种重要的系统变量,如果只管写而不考虑后面的清理工作,那就太不负责了。不知道这是哪个白痴开发者干的。甚至/etc/environment都有疑问,我把中文的各种locale都删除了,这个文件里面却还留着中文的locale,需要自己去修改。

2011-11-29更新:发现~/.dmrc也被污染了,还保留着中文语言的信息。删掉还不行,要把中文的改成英文的才可以保留下来。

2011年11月27日星期日

Supertux崩溃

在CRT显示器上开Supertux直接崩溃。看到屏幕记录里面有一条警告信息说1440x900的分辨率有问题,崩溃前的最后一条是个C++头文件的错误。想到之间在液晶显示器上还是好好的呢,可能是画面分辨率导致的问题。把~/.supertux2移走后就可以进去了。但是这样我的进度就都没有了。找到~/.supertux2/config文件,里面有fullscreen_widthfullscreen_heightwindow_widthwindow_height等配置参数,把它们改成800x600的(显示器是17寸,可以支持1024x768以下的几个分辨率)后游戏就能进去了。

有不少问题,原因可能都是配置文件过老、不兼容等问题造成的。遇到问题试试移除配置文件常常还是挺管用的。

又是显示器刷新率

之前就折腾过刷新率。17寸CRT显示器的分辨率是对的:1024x768,可是刷新率是60不是85,GNOME 3的设置里面都不能直接刷新率呢,只能改分辨率。刚用Linux的时候,也有这样的问题,那时候用Modeline来指定刷新率,现在都懒得研究Modeline了,不想花时间在这个上面。

开了Supertux后崩溃退出,显示器变成800x600@85的了。我想会不会好了呢。在GNOME 3里面把分辨率改成1024x768,刷新率竟然没有变!嗯,就这样用Supertux把显示器的刷新率设置好了。

2011年11月24日星期四

Thunderbird自动归档Gmail邮件?

通过Gmail的标签看邮件,发现只有最近一两个月的邮件在Inbox里面,别的都没有这个标签,等于是被归档了:


好几个标签都有这样的问题。根据Google的帮助,检查了一下几个filter都没有设置自动归档。后来怀疑是不是Thunderbird干的,因为我同时也在Thunderbird里面用IMAP查收邮件。搜到一个碰到同样问题的哥们,但是Mozilla的人澄清了Thunderbird是不会自动归档的,帮助里面特意强调:Messages can only be archived manually, not automatically。

不管怎么说,我把Thunderbird的归档功能禁用掉(方法在此),再观察几个月看看。用的软件越多,出问题的机会就越多,付出的维护时间就会越多。还是越简单越好!

2011年11月19日星期六

坑爹的Ubuntu

最近被Ubuntu的几个地方坑了,上来抱怨一下。

用interfaces文件配置网络接口的话,开机启动要等2分钟才能进去,显示"Waiting for network configuration...",过1分钟再显示"Waiting up to 60 more seconds for network configuration..."。这是一个影响很多人的bug,而开发者竟然说这是他们设计的特性。最后我只能是用NetworkManager来启用我的无线和有线网卡。

然后帮一个朋友恢复重装Windows之后损坏的GRUB。我很久不干这个了,因为早就不这样双系统安装了。要制作一个USB启动盘。可是dd if=file.iso of=/dev/sdX做出的启动优盘不能启动,而usb-creator-gtk选了ISO文件和优盘后,创建的按钮还是灰色的。后来从官方文档了解到,制作这个优盘启动盘需要:
  • 优盘要分区
  • 第一个分区(启动分区)要格式化成FAT16或者FAT32文件系统
  • 这个分区要加载上
真是坑爹啊,学到的标准的方法在Ubuntu这里是不适用的。

做好优盘系统进去后,按照官方文档修复GRUB。推荐的Boot-Repair根本找不到GRUB的安装。又用命令行修复,可是重启后只能进入GRUB的rescue模式,而且不能加载normal模块,说文件找不到。

后来找到原因了。正常的Linux,root文件系统进去就是标准的目录,bin、usr什么的。这个朋友用了btrfs文件系统,root文件系统进去有个@目录,@目录下才是bin、usr什么的。GRUB在(hdX,Y)找不到root,在(hdX,Y)/@才能找到root,所以Boot-Repair找不到GRUB,rescue模式下也找不到模块文件。另外,官方文档说的是(hdX,Y),而我在GRUB的rescue模式下,用ls分区发现根分区是(hdX,msdosY)这样的,所以要(hdX,msdosY)/@这样指定根分区才能找到root。

修复了GRUB后搜索,发现这是11.04及其后对btrfs文件系统特有的设计。又是Ubuntu一大奇葩的特色,打破常规,让你学到的东西在Ubuntu里面再次失效。

2011年11月14日星期一

换行符引起的麻烦

用sed处理一个hosts文件,内容都是类似下面的行:
203.208.46.180 www.google.com
203.208.46.180 music.google.com
203.208.46.180 music.googleusercontent.com
203.208.46.180 music-streaming.l.google.com
203.208.46.180 large-uploads.l.google.com
IP地址和域名之间是用Tab分割的。想用sed把这个文件处理成dnsmasq的DNS记录配置内容,用如下的命令:
sed -e 's|^\(.*\)    \(.*\)$|address=/\2/\1|g'
两个引用的中间是一个TAB。期望的结果如下:
address=/www.google.com/203.208.46.180
address=/music.google.com/203.208.46.180
address=/music.googleusercontent.com/203.208.46.180
address=/music-streaming.l.google.com/203.208.46.180
address=/large-uploads.l.google.com/203.208.46.180
但实际结果出乎意料:
/203.208.46.180ogle.com
/203.208.46.180google.com
/203.208.46.180googleusercontent.com
/203.208.46.180streaming.l.google.com
/203.208.46.180uploads.l.google.com
不但IP和域名的顺序没有调换,域名前面的几个字符还被覆盖了。后来想是不是因为文件换行符的问题。用Vim打开发现果然是DOS格式的换行符。把脚本改一下就可以得到正确结果了:
sed -e 's/^M$//g' -e 's|^\(.*\) \(.*\)$|address=/\2/\1|g'
错误结果也比较好解释了。Windows下的换行符是Carriage Return + Line Feed(\r\n),Linux下的换行符是Line Feed(\n)。Carriage Return就是打字机的打印头回到行首,Line Feed是指纸出来一行,这样打印头就处在下一行的同一个位置了。sed命令中的第二组引用不但包括了域名,还包括了紧随其后、位于 \n前的\r,这样本来应该位于\2后面的/\1,现在要从\2的开头开始打印了,于是就覆盖了域名的前面几个字符。例如对第一行:
address=/www.google.com/
/203.208.46.180
把开头的address=/www.go都覆盖了,所以结果就是:
/203.208.46.180ogle.com
后面的也都要覆盖掉IP长度+1(/)的字符。

2011年7月11日星期一

No input file specified错误解决方法

用的Nginx和php-fastcgi,如果URI是不存在的PHP文件,那么浏览器显示"No input file specified." 这个错误(应该)是php-fastcgi找不到对应文件出现的。解决办法是让nginx知道这个错误。参见Stackflow上的解决办法

Nginx的404问题

在本机(Ubuntu 11.04)上装了个nginx来预览主页内容,发现没有404页面,乱敲个URI都显示的是首页。我自然就去找404相关的设置了。加上如下配置:
error_page 404 /404.html;
location = /404.html {
    root   /usr/share/nginx/html;
}
之后还是没有变化。然后发现了这样一段配置:
location / {
    # First attempt to serve request as file, then
    # as directory, then fall back to index.html
    try_files $uri $uri/ /index.html;
}
把这段注释掉就好了,404也正常了。 Ubuntu为啥要默认这样的坑爹配置呢?CentOS 5.5没有这个问题。

2011年5月31日星期二

死机问题解决

笔记本电脑十几天没有关机了(只休眠),今天恢复后输入无线路由器密码(有bug记不住密码),然后就死机了,内核挂了。重试多次都这样。用网线连接后检查升级,也没有可用的升级。无奈用台式机登录,把无线路由器的信道由自动换成一个固定的后重启路由器,结果笔记本发现不了无线路由器。又把信道换回自动再重启路由器,笔记本连接无线路由器后再没有死机。

解决这个问题的核心,是找到问题出在wifi上。不能变动(升级)内核,那就变动无线路由器来尝试解决。

2011年4月30日星期六

系统升级后对用户配置文件的处理

升级到Ubuntu 11.04后,Ubuntu Classic的桌面特效出问题了。在Launchpad上找了一圈,也没有看到有人汇报切合我问题的Bug,所以估计是特例,自己提交上去也得不到共鸣和解决。再次研究,终于搞定了。

我研究了家目录下的一些目录,比如.gnome2,删除掉compiz相关的目录。然后全面搜查一遍(要在家目录下):
tux@dell:~$ find . -iregex "\./\..*compiz.*"
在.gconf/apps里面还有东西。把找到的文件都删除掉,注销再登入就好了。如果还不行,可以grep -R *试试吧。

其实很多时候软件升级带来的Bug并不是软件本身的Bug,而是因为用户家目录下的配置文件造成的。也许是新的软件和老的配置文件不兼容,所以软件就会出毛病。如果配置文件不是特别重要,可以把所有在家目录下相关的配置都删除掉(做必要的备份),很可能就可以解决问题了。

我们不能指望发行版在升级软件的时候,还考虑到用户配置文件的迁移和升级,发行版只能考虑到系统配置文件的升级。我之前一直特别自豪于Linux下的配置文件可以用好几年。即使要重装系统,因为家目录总是单独分区的,所以用户配置还可以在新系统下接着使用。现在看来,系统升级后如果出现Bug,用户有必要对家目录下以点 (.)开头的配置文件进行必要的核查,并采取必要的措施。

2011年4月25日星期一

Ubuntu 11.04和GNOME3

一时无聊升级了到了Ubuntu 11.04(离正式发布还有几天),结果桌面特效不能用,而且不论是Unity还是Ubuntu Classic,对我双显示器的支持都有问题。好吧,那就试试GNOME3。又升级到了GNOME3,对双显示器的支持都很糟糕,而且界面很不习惯。我已经把GNOME 2调教得非常顺手和方便了,鼠标到桌面左下角显示桌面,桌面右下角显示窗口缩略图(Exposé),窗口直接在两个工作空间(Workspace)之间拖动。没有桌面特效这两个功能都没有了。

于是就把GNOME3降级到了GNOME2。把源改回10.10的,然后一个一个包地降级,竟然成功了。11.04的桌面特效也没有,就试着把11.04的桌面降级到10.10。折腾很久,无奈还是无法手动解决apt的dependency hell,就改回11.04的源,恢复到了11.04。没有桌面特效,很不爽!不折腾了,开始做事情。

2011年4月12日星期二

内存大小

经常看到有人询问Linux下的内存大小小于实际安装的内存。这是因为内核有保留部分内存使用。

台式机:
$ dmesg |grep Memory
[ 0.000000] Memory: 3457776k/4980736k available (5716k kernel code, 1313348k absent, 209612k reserved, 5375k data, 912k init)
3457776+1313348+209612=4980736

笔记本:
$ dmesg |grep Memory
[ 0.000000] Memory: 2002160k/2056956k available (5716k kernel code, 452k absent, 54344k reserved, 5375k data, 912k init)
2002160+452+54344=2056956

某VPS:
$ dmesg|grep Memory
[ 0.000000] Memory: 603080k/629760k available (2591k kernel code, 388k absent, 26292k reserved, 5287k data, 460k init)
603080+388+26292=629760

不过另一个VPS上的数据稍微有点出入:
$ dmesg|grep Memory
[    0.000000] Memory: 107040k/131072k available (5434k kernel code, 384k absent, 23488k reserved, 5022k data, 448k init)
107040+384+23488=130912

结论,系统保留的内存大小是absent+reserved的和。

最近在自己的Wiki上活跃了,那里更适合一些探索性的东西。

2011年4月1日星期五

Evince看PS文件

我用evince <(man -t man)来看PS格式的man page。这样evince可以正确显示页数,但是却加载不出来页面。我在Freenode的#bash里面请教,有人说可能是evince需要像lseek()一样对文件进行seek,可是对Bash的Process Substitution却无法seek。我觉得有可能是这个原因。

2011年3月30日星期三

如何清空一个文件

$ >file

find的正则表达式

水木上有人问:SHELL如何只list名称是8个数字的文件夹?用ls [0-9](重复9次),或者结合grep可以做到。但是用find怎么做呢?研究了一会儿才给出答案:
find . -type d -regextype posix-egrep -regex '.*/[0-9]{8}'
find-regex不是搜索,而是要匹配整个的路径,所以正则表达式前面要加.*/。默认的正则表达式类型是Emacs类型的。虽然Emacs的正则表达式支持\{\}的重复,但是在find的info里面写到是不支持的,要改成posix-egrep类型的正则表达式就可以用{}了。

2011年3月23日星期三

DBus揭密

昨晚折腾够呛,看代码找GNOME的休眠命令。正好看到Rex写的一篇“基本的 DBus 偵錯技巧
”,用D-Bus提供的工具来解剖程序,要比看代码操作容易多了。比如用如下命令:

dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.UPower /org/freedesktop/UPower org.freedesktop.UPower.Hibernate
即可执行休眠操作。不过这个操作是试图直接休眠,要比在GNOME中的休眠少一些操作,例如检查能不能休眠、休眠前锁定屏幕等。

以前看到D-Bus这个东西,总觉得挺抽象、比较底层,没有去研究过,看了Rex的这篇文章,结合自己昨天看代码的经历,一下就对D-Bus去神秘化了。

2011年3月22日星期二

寻找GNOME的休眠命令

为了试验Mac OS X Snow Leopard,把笔记本电脑硬盘全部格式化了。后来又重装了Ubuntu 10.10,但是休眠功能不行了。试着装了hibernate包,再休眠又可以了,在屏幕上可以看到hibernate包的s2disk命令存储内存印象的进度。卸载了hirbernate包,又不能休眠了。可是重装前的Ubuntu 10.10,不用装hibernate也可以休眠的。

记得上大学时候在实验室很旧的计算机上装的Breezy Badger(Ubuntu 5.10),是可以休眠的,可是自己的电脑就没法休眠。现在家用的台式机也是Ubuntu 10.10,没有装hibernate也可以休眠。

我就想知道在GNOME里面点击“Hibernate”后,到底执行了什么命令来休眠?装了hibernate用的是它的s2disk,那么不装的时候呢?我想一切皆有缘由的。

先Google了一下,和/usr/lib/indicator-session/gtk-logout-helper(由indicator-session提供)有关系。apt-get了indicator-session和indicator-applet的源代码,但是没有找到线索。倒是/usr/bin/gnome-session-save --shutdown-dialog(由gnome-session-bin提供)可以弹出关机的提示框:

用apt-get下载源代码,用grep大法搜索hibernate,在gnome-session的gsm-manager.c里面找到了如下的代码:

static void
manager_attempt_hibernate (GsmManager *manager)
{
        gboolean  can_hibernate;
        GError   *error;
        gboolean  ret;

        can_hibernate = up_client_get_can_hibernate (manager->priv->up_client);
        if (can_hibernate) {

                /* lock the screen before we suspend */
                manager_perhaps_lock (manager);

                error = NULL;
                ret = up_client_hibernate_sync (manager->priv->up_client, NULL, &error);
                if (!ret) {
                        g_warning ("Unexpected hibernate failure: %s",
                                   error->message);
                        g_error_free (error);
                }
        }
}


里面的up_client_hibernate_sync应该就是执行具体休眠操作的函数了。可是这个函数从哪里来呢?我没有什么浏览源码的工具,只有find、grep和vim。其实Google基本就够了,直接Google搜索这个函数名,哦,原来是upower的函数。再apt-get下来upower的源代码,这个函数在upower的libupower-glib/up-client.c里面,是这么写的:

gboolean
up_client_hibernate_sync (UpClient *client, GCancellable *cancellable, GError **error)
{
        gboolean ret;
        GError *error_local = NULL;

        g_return_val_if_fail (UP_IS_CLIENT (client), FALSE);
        g_return_val_if_fail (client->priv->proxy != NULL, FALSE);

        ret = dbus_g_proxy_call (client->priv->proxy, "Hibernate", &error_local,
                                 G_TYPE_INVALID, G_TYPE_INVALID);
        if (!ret) {
                /* DBus might time out, which is okay */
                if (g_error_matches (error_local, DBUS_GERROR, DBUS_GERROR_NO_REPLY)) {
                        g_debug ("DBUS timed out, but recovering");
                        ret = TRUE;
                        goto out;
                }

                /* an actual error */
                g_warning ("Couldn't hibernate: %s", error_local->message);
                g_set_error (error, 1, 0, "%s", error_local->message);
        }
out:
        if (error_local != NULL)
                g_error_free (error_local);
        return ret;
}


dbus_g_proxy_call函数执行了实际的休眠操作,Google一下立刻得到其文档。至于这个“Hibernate”的method怎么调的,我不懂DBus,没搞清楚。歪打正着地在src/linux/up-backend.c里面找到了答案:
#define UP_BACKEND_SUSPEND_COMMAND              "/usr/sbin/pm-suspend"
#define UP_BACKEND_HIBERNATE_COMMAND            "/usr/sbin/pm-hibernate"
#define UP_BACKEND_POWERSAVE_TRUE_COMMAND       "/usr/sbin/pm-powersave true"
#define UP_BACKEND_POWERSAVE_FALSE_COMMAND      "/usr/sbin/pm-powersave false"
原来用的硬盘上的pm-hibernate命令(由pm-utils包提供)。这个命令的落实,在/usr/lib/pm-utils/pm-functions脚本里面可以找到:
do_hibernate()
{
        [ -n "${HIBERNATE_MODE}" ] && \
        grep -qw "${HIBERNATE_MODE}" /sys/power/disk && \
        echo -n "${HIBERNATE_MODE}" > /sys/power/disk
        echo -n "disk" > /sys/power/state
}
好了,就此打住了。至于HIBERNATE_MODE的设置,再不往下追究了,否则就没完没了了。

找到这个休眠命令的过程很纠结。以后要提高开发本领,至少是读代码的本领,才能在类似的postmortem分析中快速找到答案。

2011年3月19日星期六

更舒服地阅读man

很多man页我都没有读完过,只是用作参考。一个原因是很多man页太长了。某天发现了man的-t参数,可以把man页处理成Postscript文件,方便打印了。我用
man -t 7 regex > regex.ps
生成了PS文件,打开一看才Letter纸上两页过一点。原来在less里面看,看不出有多长,如果要翻页几次,就觉得挺长的了,现在转成PS发现一点并不长。于是打印出来精读了两遍,很受用。

用PS文件看,可以看到页数,定位、阅读的时候是以页作为单位的,可以放大、缩小,缩小后可以一眼扫到很多东西。这些要素让man页的阅读体验大大增强,效率得到了提高。虽然我们都很习惯在终端阅读man了,但是这种阅读方式明显是有缺陷的。

我干脆写了一个叫pdfman的脚本,用来生成man页的PS文件并调用Evince打开这个PS文件。PS文件在Evince中是无法选取和查找的,所以要看PDF的话,就要先用ps2pdf把PS文件转换为PDF文件。

我现在如果要细读man页,就用pdfman,打印出来就更好读了;如果是查找个参数什么的,就用正常的man,因为最常用的可能就是用'/'来查找关键字了,less里面很方便。

所以,是时候用PS来看man了!

2011年3月14日星期一

GNOME显示器分辨率的设置


最近在笔记本上外接了我已经退休的15寸CRT显示器,这样切换屏幕面积变大,多窗口使用比较方便。这台显示器最大支持1024x768@85Hz,但是“显示器首选项”里面比这个分辨率高的还有三个,最高是1280x1024@60Hz。这个刷新率比较低,不太习惯。

每次在“显示器首选项”里面关闭CRT再打开的时候,默认的分辨率就是最高的,还要用鼠标去选择1024x768的分辨率和85Hz的刷新率才行。我想把高的三个删掉,但是在Xorg.conf、在gconf-editor里面都没有找到。最后只好来地毯式搜索了:
tux@dell:~$ find . -name '.*' | grep -R 1280
结果是空的。
再来:
root@dell:/home/tux# find /etc -type f -print0 |xargs -0 grep -R 1280
/etc/gnome-settings-daemon/xrandr/monitors.xml: 1280
…………
第一个就抓到了,原来在/etc/gnome-settings-daemon/xrandr/monitors.xml里面。因为在“显示器首选项”里面选了设为默认,需要认证sudo,所以设置应当是保存在了系统目录里面。

但是打开这个文件就发现,里面保存的是各模式的组合,而不是这些模式本身。研究发现GNOME是从xrandr获取的可用模式:
tux@dell:~$ xrandr
Screen 0: minimum 320 x 200, current 2390 x 768, maximum 8192 x 8192
VGA1 connected 1024x768+1366+0 (normal left inverted right x axis y axis) 306mm x 230mm
   1280x1024      60.0 
   1280x960       60.0 
   1152x864       75.0 
   1024x768       85.0*    75.1     70.1     60.0 
   832x624        74.6 
   800x600       100.0     85.1     72.2     75.0     60.3 
   640x480       100.0     85.0     72.8     75.0     60.0 
   720x400        70.1 
   640x350        70.1 
LVDS1 connected 1366x768+0+0 (normal left inverted right x axis y axis) 309mm x 174mm
   1366x768       60.0*+
   1360x768       59.8     60.0 
   1024x768       60.0 
   800x600        60.3     56.2 
   640x480        59.9 
DP1 disconnected (normal left inverted right x axis y axis)
这些模式是GNOME实时获得的,貌似不是从什么配置文件获得的。顺便把一个3年多前问这个问题的帖子也给回答了。:-)
右边屏幕分辨率:1280x1024
右边屏幕分辨率:1024x768
最后发现把显示器分辨率设置成1024x768还有一个好处。笔记本的分辨率是1366x768,这样两个显示器的高度一样,整个桌面是一个整齐的长方形。如果设置成1280x1024,那么笔记本电脑比较矮,在它屏幕的下方就有一块1366x256黑块。虽然用的时候看不到,但是GNOME是把那里也当成桌面的。我的桌面特效里面把鼠标挪到左下角显示桌面,这样的话要把鼠标挪到看不到的黑块的左下角才能显示桌面。

2011年3月11日星期五

SSH上不去

新建了个测试用户,结果远程登录上不去。看了这个用户没有家目录,还以为这样不行呢。但建了也上不去。是不是设置了knockd?没有。是不是端口改成了不是22的?也不是。最后打开IBM DW上的《保护 SSH 的三把锁》这篇文章,因为我照着这个配置过。一看还有一把锁是用PAM限制登录用户,原来我用PAM设置了两个用户能用SSH登录上来。有时候做了一些不常用的配置,时间长了就记不清了。出了问题想不起来就有点麻烦了。

sudoers的语法

以前没有学习过sudoers配置文件的语法,给自己的普通账号赋予所有的权限,例如:
tux  ALL=(ALL) ALL
或者
%wheel ALL=(ALL) ALL
或者
%admin ALL=(ALL) ALL
Ubuntu下都不用修改,因为安装时候添加的用户已经给放到了admin组。但要是多用户的服务器,这么做就不够了。sudo的配置文件提供了精细的配置选项,可以为用户、运行身份、机器和命令设置多个别名,分别是:User_Alias、Runas_Alias、Host_Alias和Cmnd_Alias。

关键的语句是User Specification,指定了谁在哪里以什么身份可以做什么:
tux ALL= (ALL) ALL
谁(用户) 在哪里(机器) 什么身份(运行身份) 做什么(命令)
可以通过前面提到的四种别名进行更细的设置,详见sudoers(5)。

2011年3月10日星期四

rsync同步的问题

我用自己写的台式机和笔记本之间进行同步的脚本,把笔记本上昨晚下载的Redhat Enterprise Linux 6.0的DVD镜像同步到台式机。脚本里面是用rsync同步,但是发现这个DVD光盘不在要同步文件列表里面。是不是文件太大了呢?打开rsync的man,看到里面有个-max-size选项,指定传输文件的最大尺寸。我指定到很大之后,还是没有这个DVD镜像。把rsync的源代码包下载下来,也没有找到这个值的默认设置。

 我的rsync选项是:
OPTIONS="--archive --delete --backup --backup-dir=/home/tux/.rsync/backup/ --suffix=@ --partial --partial-dir=.rsync-partial --update --progress --itemize-changes"
我检查可疑的选项。看到--update选项的作用是如果目标文件的修改时间比源文件新则跳过。我打开台式机的目录一看,里面已经有这个DVD了,是刚刚复制、粘贴一半又取消剩下的十几兆大的一个文件。把这个文件删除了,再同步就可以了。

以前加上--update选项是为了避免在一端新修改的文件在被另一端的覆盖。但是从这事情看,这样可能让同步内容不能完整传送过去。我现在去掉了--update选项,这样总是会完全同步的,但在确认前始终要检查一遍要执行的操作。

2011年3月7日星期一

yum的autoremove功能

Debian下apt-get有个autoremove功能,可以卸载不再需要的被依赖(depended)包:
autoremove
           autoremove is used to remove packages that were automatically
           installed to satisfy dependencies for some package and that are no
           more needed.
但是yum没有这个命令,而且也没有这样的功能。比如我刚刚安装了vim-enhanced,同时新安装了一堆被依赖包,这些包都是只被vim-enhanced依赖的。yum remove vim-enhanced只会卸载vim-enhanced,而不会卸载这些依赖包,这样卸载完后这些包都成了无用的包。

目前可以安装yum-plugin-show-leaves插件,在yum输出的最后显示新的leaves(不被其它包依赖):

不过这个东西也不靠谱,vim安装的依赖包可不止最后的gpm-libs、ruby-libs和vim-common这三个,我在yum.log里面又找到了好多:
前12个都是vim依赖的包,我要都在命令行指定删除。这很麻烦的。

找到一篇文章,yum里面已经提供了类似的功能,不过在Fedora 14里面还没有出现。但愿这个功能能够普及。

2011年3月4日星期五

坑爹的Fedora

安装Fedora 14,我不需要桌面,可是都联网下载软件了也没有让我选择安装什么类型(桌面、服务器等)。网上搜了下,说最后一步才是选择安装类型。又试了试,果然是联网下载一会儿才问我安装的软件集:
貌似Ubuntu是安装开始就问的。感谢Fedora给我的惊喜。

不给力的因特尔

在VirtualBox里面安装Fedora 14 x86_64版本失败,显示如下错误:
This kernel requires an x86-64 CPU, but only detected an i686 CPU.
Unable to boot - please use a kernel appropriate for your CPU.
VirtualBox的文档说允许64位客户机要打开APIC支持,我打开后还是出现一样的错误。再看文档,原来需要硬件虚拟化支持:
VirtualBox's 64-bit guest support (added with version 2.0) and multiprocessing (SMP, added with version 3.0) both require hardware virtualization to be enabled. (This is not much of a limitation since the vast majority of today's 64-bit and multicore CPUs ship with hardware virtualization anyway; the exceptions to this rule are e.g. older Intel Celeron and AMD Opteron CPUs.)
我的本本是Dell Inspiron 14v,CPU是因特尔奔腾T4500,不支持VT-x技术。以前攒台式机的时候就要求CPU一定得支持硬件虚拟化,调研发现Intel偏低端的CPU就是不支持VT-x,而AMD就厚道多了,64位的CPU基本都支持AMD-V,最后选择了AMD的CPU。

Unattended Upgrades

Ubuntu下的unattended-upgrades包可以自动安装安全更新。apt包提供的/etc/cron.daily/apt文件可以识别unattended-upgrades的设置,该设置在/etc/apt/apt.conf.d/10periodic中定义。默认是不启用的,要添加
APT::Periodic::Unattended-Upgrade "1";
到10periodic中方可。
在GNOME菜单的“软件源”中,若勾上“不确认就安装安全更新”,则立刻在10periodic文件中添加该行。

多说一句的是,10periodic文件是由update-notifier-common包提供的:
# apt-file search 10periodic
update-notifier-common: /etc/apt/apt.conf.d/10periodic

2011年2月28日星期一

dnsmasq的错误

DNSmasq出现如下错误:
tux@Neverland:/usr/share/virtualbox$ sudo service dnsmasq restart
 * Restarting DNS forwarder and DHCP server dnsmasq                            
dnsmasq: failed to bind DHCP server socket: Address already in use
                                                                         [fail]
看起来是端口被占用了。原来还开着bind9呢。把bind9禁止了就好了。

显卡驱动失效

昨晚来了个telinit 1之后,再进去桌面特效就没有了,就先放一边了。后来发现VirtualBox里面的Windows XP都打不开了,出现NS_ERROR_FAILURE (0x80004005)的错误:
 这个不像是内核模块的错误,因为没有其它的错误了。dmesg发现如下信息:
Feb 27 22:46:51 Neverland kernel: [10061.463577] VBoxTestOGL[5390]: segfault at 4 ip 00007f4af0c6938e sp 00007fff6a44cfd0 error 4 in libGL.so.1.2[7f4a f0c0e000+ae000]
看来是显卡驱动没有加载,不支持OpenGL了。而我在XP虚拟机里面打开了3D加速,这个需要宿主机支持OpenGL的。当时由于显卡驱动的问题,这两个复选框都是灰的,没法去掉。下图是恢复后的样子。
今天再次打开ATI的驱动设置,当然是出错消息,但是提示用aticonfig设置。然后就用aticonfig --initial一下,然后重启桌面,桌面特效好了,虚拟机也能启动了。

以后要记得aticonfig这个命令来初始化显卡驱动。

2011年2月5日星期六

AWS上的VPN

AWS上的主机可以当个VPS使用,而且还一年免费呢。Linux AMI (Amazon Machine Image)的说明书上说:
In addition, this version of the Amazon Linux AMI has been built to be binary compatible with the CentOS 5.x series of
releases, and therefore packages that are built to run on CentOS should run on the Amazon Linux AMI as well.
我把CentOS 5.5的源加上去,还是没法直接兼容的,比如yum的$releasever这个变量都是2010.10,不是CentOS的版本号。可惜PPTPd在源里面都没有,下载了Redhat企业版5的RPM包,安装上去后连接始终出错,但是找不到原因。随便搜了一下,发现某帖子说在CentOS上PPTP装上去不能用,就用了里面提供的安装脚本。原来是下载SRPM包编译安装的PPTPd。我倒是多年不用,忘了编译安装软件这个办法了。用这个脚本安装的是可以用的,就再没有自己从头编译折腾。

2011年2月2日星期三

Picasa的字体替换


Picasa 3下面的汉字是方块,以前解决了,后来又忘了怎么弄的。其实在Picasa Font Settings这个程序里,给Tahoma(Picasa默认的界面字体)添加一个中文备用字体就可以了,我用的是文泉驿Micro Hei。Picasa是自己带Wine的,不依赖系统发行的Wine,所以设置Wine是没有用的。

Update 2011-11-07: 对话框中的中文字体还是方块,把/opt/google/picasa/3.0/wine/drive_c/windows/inf/picasa.inf里面的
HKLM,Software\Microsoft\Windows NT\CurrentVersion\FontSubstitutes,"MS Shell Dlg",,"Tahoma"
改成
HKLM,Software\Microsoft\Windows NT\CurrentVersion\FontSubstitutes,"MS Shell Dlg",,"WenQuanYi Micro Hei"
即可解决。来自Yu Wang's Blog

台式机故障

昨晚还好的,今天开机就显示器不亮,鼠标、键盘也没有得电。想起这个电脑以前也有过类似的问题,是按住机箱的复位键一会儿松开后,就会正常启动了。发生故障的时候,电脑噪音较小,正常启动后噪音也恢复正常。怀疑是电源的问题让系统无法正常启动。以后出现故障,要及时记录下来症状和解决办法以备后续查询。

2011年1月24日星期一

多个A记录

最近尝试了一下多域名。域名是在name.com上放的,共两个A,但是两个地方的网页内容不同。

用w3m/0.5.2上,每刷新一次地址都变,很规律。Opera/11也变得比较勤,Firefox/3.6和Chromium/8要迅速刷几下才变。ping每次都变,OpenSSH是每次都调换顺序,如果第一个连接失败就换到下一个IP。Opera mini/5会变,Android/2.2(虚拟机)没见到变。Windows XP下的Safari/4、Chrome/8和IE/8都没看到变的。

我只是试验了下几个客户端的表现,其实还不知道服务端的策略呢。其实下面的回答就很概括了:
moi: 那客户得到的哪个?
任晓磊: 服务器可以按多种顺序输出,客户端也可以对顺序有自己的理解
如果www.example.com指向两个服务器,而这两个服务器同时也有SSH服务,那么SSH的时候,就不能确定连接那个服务器了。这时候就需要新设置A记录了,比如给admin.example.com设置单独的A记录,来作为SSH连接的主机。

发送自我的Windows Mobile 电话

2011年1月22日星期六

智能DNS

DNSPod网站提供了智能DNS,免费版本可以设置默认、电信、联通和教育网四个类型。如果在不同区域都有服务器,可以把各区域的A记录列到对应线路类型里面:

上面的除了最后一个IP是教育网的,其它两个都在国外,只是为了试验这个功能。

在域名注册的地方把NS改为DNSPod的,等了一天了还有地方没有生效,相比在name.com那里,改了几乎马上生效。这样在我联通的宽带访问,对应的IP就是第二个;在国外访问,就是默认的第一个。

DNSPod号称提供宕机检测,就是如果发现一个记录失效后,自动从列表中移除该记录,以让客户端解析到正常的记录上。但是免费版的并不提供这个功能,上当了。我是找国外免费的DNS failover服务,什么zoneedit, editdns, dnsmadeeasy, dyndns, freedns都看了,都没有免费的。

实际上这样的DNS failover是很被诟病的。经过我试用DNSPod的免费服务,记录修改后传播非常慢,而且在这个过程中,不同ISP网段下DNS的解析结果都不一样,很混乱。如果实际使用中这么混乱,问题可能比麻烦还多。

备份服务

不小心把FreeBSD搞宕机了,上面有主页,还有一些自己的Web服务。这个机器一时还没人给我去看,既然还有别的机器,就搞个服务的备份吧。最简单的备份,就是宕机后把域名的A记录改到新地址,然后在新机器上从桌面电脑同步一份主页的内容上去。这样把主页恢复了。

几个动态的站点只有FreeBSD上有,现在没法复制,就弄了一个恢复页面。所有的URI都定向到maintenance.php文件,要保证URI是maintenance.php的时候可以正常显示PHP文件:
server {
    listen 80;
    server_name *.fossilet.org;
    access_log  /var/log/nginx/fossilet.access.log;
    rewrite ^(.*)$ http://fossilet.org$1 permanent;
}

server {
    listen 80;
    server_name fossilet.org;
    access_log  /var/log/nginx/fossilet.access.log;
    root /var/www/fossilet;

    location / {
        if (-f $document_root/maintenance.php) {
            return 503;
        }
        index index.php index.html index.html;
    }

    error_page 503 @maintenance;
    location @maintenance {
        rewrite ^(.*)$ /maintenance.php break;
        fastcgi_pass    127.0.0.1:9000;
        fastcgi_index   index.php;
        fastcgi_param   SCRIPT_FILENAME /var/www/fossilet$fastcgi_script_name;
        include         fastcgi_params;
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /var/www/nginx-default;
    }
}

2011年1月20日星期四

nginx的问题

弄个维护页面(PHP),可是所有PHP都显示Temporarily unavailable。以为是配置的问题。看error.log,是fastcgi的网关处理超时。再检查配置文件的时候,发现fastcgi的网关写成了128.0.0.1。真是低级的错误啊。可能是远程登陆上去速度很慢,切换screen的时候在Vim里面Ctrl-A正好把127增加到了128。

Firefox崩溃

下了个Firefox 4 beta 9,结果插件都不认,AutoProxy没法用,遂退回3。可是之后3持续崩溃,安全模式(-safe-mode)也无助。发现Firefox还有一个-g选项用来debug,是用gdb调试的。打开后start命令开始,发现Segmentation fault,出在/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/IcedTeaPlugin.so。用dpkg -S查找,是icedtea6-plugin这个包里面的。这个包是给Firefox提供Java Applet支持的,现在很少有网页用Applet了(我是为了看time.gov网站的时间才装的)。卸载掉这个包Firefox就正常了。

Firefox诡异的问题

改nginx虚拟主机配置,改完后reload,可是Firefox里头还是旧的内容。反复检查nginx的配置也没看出问题,然后打开Chromium上就没有问题。把Firefox的缓存清了之后,Firefox也没问题了。有时候Ctrl-F5刷新也没有效果,必须手动清楚Cache才行。

有时候出了问题,关键是找到问题产生的来源在哪里。用同类的其他工具进行试验,或者换个环境、参数试验,往往会很有帮助。

发送自我的Windows Mobile 电话

Python序列索引

s[i:j:k]的i和j是头和尾,k是步长,我却把中间的j当成了步长,再加上负数索引就更纠结了。代码:
s="foobar"
k=3
''.join([chr(ord(c)+1) for c in s[-1:-k-1:-1]])
其实用range可读性更好:
''.join([chr(ord(s[-i-1])+1) for i in range(k)])
发送自我的Windows Mobile 电话

2011年1月19日星期三

Google Apps的域名设置

Google Apps Sites可以给站点设置地址映射,这样可以用自己的域名来提供网页访问,如http://www.example.com,而不用https://sites.google.com/a/example.com/<sitename>。

其他的服务也可以修改网址,我想把Docs的网址改成自己的域名,然后再改CNAME,就不用翻墙,手机可以直接用了。中午试了,可惜发现别的服务改的网址都是重定向到Apps的登录页面,而不是像Sites一样全面的网址映射。这也难怪,因为别的服务都是HTTPS的,如https://docs.google.com/a/example.com,如果域名换成用户自己的,如http://docs.example.com就没法提供SSL加密了,要加密就不能用Google的证书了。

发送自我的Windows Mobile 电话

2011年1月17日星期一

FreeBSD发行版的生命周期

昨天发现FreeBSD服务器上的6.3已经支持期过了,就要升级,才发现只能升级7.3了(7.1版1月31号就到期了)。原来FreeBSD的发行版支持期只有1~2年啊,比我想象得要短,我以为像FreeBSD这样的服务器系统,应该是很稳定的,支持期很长呢。这里有图示,还有Ubuntu发行版的生命周期图示做对比。

2011年1月16日星期日

开始用Google Sites

以前用Google Sites写过几个网页,都是试试玩的。最近看到Android x86的网站是在Google Sites上创建的,然后就打算把我的个人主页也转到Google Sites上,以后新加的网页将在Google Sites上建立。如果还像以前一样用Vim写,效率还是比较低下,而且要自己做所有的维护工作。

第一个网页要在里面嵌入一个Google电子表格,Google Sites都直接支持插入的,所以非常方便。但是Google Sites的容量没有Google Apps Sites的大,于是又把网站从Google迁移到Google Apps。

初步了解了下在网页里面可以使用的GadgetsApp Script。以前没有接触过这些东西,所以花时间研究了下才知道这些东西怎么用。感觉Google提供的服务,不仅用起来很好,而且深层次的二次开发手段也很丰富,真是好东西啊。

我想在网页下面自动显示网页的最后更新时间,用Gadgets和App Script都试验了一下,还没有搞定。

如果要用自己的域名来访问Google Sites或者Google Apps Sites,需要把域名的CNAME指到ghs.google.com,可是这个是被中国大陆的防火墙屏蔽的, 需要采取点手段才能让网站不翻墙也在国内使用。我是用的you8g.com提供的服务。

2011年1月12日星期三

Debian菜单

Ubuntu下的Debian菜单里面有时候会有无效的项目,它们在~/.local/share/applications/menu-xdg下面。在这个目录里面rm -rf *看起来没什么伤害,Debian菜单里面的项是用menu包的update-menus命令生成的。

2011年1月9日星期日

Ubuntu版本生命周期图

一直想画一个甘特图一样的Ubuntu版本生命周期图,这样就可以直观地看到当前哪些版本还是官方支持的,以选择使用的版本,或者升级过期的系统。

每次遇到画图,就不知道选啥工具。这次用Ipe画了画,要精确到月的话太费劲了,精确到天就更不能想象了。后来决定用甘特图工具画好了,这样可以自动地处理日期,生成生命周期图。其实我想到用PSTricks肯定可以画得既漂亮又精确,但是这个是Tex的,太花时间了,还是作罢。最后在Google Docs里面找了个甘特图模板画的。
下面是嵌入的甘特图,RSS订阅的可能看不到,要进入文章原始页面查看。

电子表格文件的Google Docs链接

VirtualBox的鼠标

装了Android,发现没有鼠标,后来Google了一下,要把Absolute pointing device去掉:
手册里面是这么写的:
 Enable absolute pointing device
If enabled, VirtualBox reports to the virtual machine that a USB tablet device is present and communicates mouse events to the virtual machine through this device. If disabled, mouse events are communicated through a traditional PS/2 virtual mouse device. Using the virtual USB tablet has the advantage that movements are reported in absolute coordinates (instead of as relative position changes), which allows VirtualBox to translate mouse events over the VM window into tablet events without having to "capture" the mouse in the guest as described in the section called “Capturing and releasing keyboard and mouse”. This makes using the VM less tedious even if Guest Additions are not installed.[11]
原来如果是触控板输入,那么这样可以把虚拟机和宿主机的位置统一起来,比较省心,但是如果是普通鼠标,不能勾上这一项。

修复GRUB

从第一次使用Linux(Red Hat 9.0)时候,就需要学会修复GRUB。因为安装Windows的时候,会把GRUB的引导信息覆盖掉。那时候是用Redhat 9.0的光盘启动,进入修复模式,光盘会找到已经安装的系统。chroot进去后,grub-install /dev/hda就可以了。

后来用了Debian,Linux用了udev,在/dev下的设备名是动态生成的,而不是像以前一样静态的,不管有几块硬盘,/dev/hda1、2什么的一堆都有。

这样子如果用Live CD启动,Live系统的/dev下面是没有硬盘设备名的。这里需要用mknod手动生成:
# mknod /dev/sda1 b 8 1
然后挂载要修复的系统再chroot进去:
# mount /dev/sda1 /mnt
# chroot /mnt
进去后还要再生成/dev/sda:
# mknod /dev/sda b 8 0
然后安装grub即可:
# grub-install /dev/sda
mknod要创建的设备名的大号和小号在/usr/src/linux/Documentation/devices.txt。

Android初体验

今天在VirtualBox里面装了Android玩,不用买手机就可以体验Android了。Android-x86这个项目把Android移植到了x86平台,在这里下载

一开始我用的froyo-vm-20100812.iso(2.2),用起来图形很卡,而且装到硬盘上之后进不去。后来用了一个现成的1.6版的虚拟器件,进去不卡,但是网络不通。再用froyo-eeepc-20110101.iso,不卡了,网络也正常。还用了老一点但是稳定版的android-x86-1.6-r2.iso,也没有问题。



台式机上没有WIFI网络,定位功能没法用,就试着在我的Dell Inspiron 14V上装1.6和2.2,Linux能进去,但是图形界面都出不来。毕竟不是拿个笔记本就能兼容的。

2011年1月8日星期六

VirtualBox的硬件3D加速

今天要在VirtualBox的Windows客户机下试验一个Vega Prime的例程,打开的时候vbox弹出如下的对话框:


是说要在客户机里面借用宿主机的硬件3D加速,Guest Additions的版本要和vbox的版本一致。我一看Windows状态栏Guest Additions的版本才是2.1.4,而vbox的版本是3.2.8。这个Guest Additions是宿主机里面的/usr/share/virtualbox/VBoxGuestAdditions.iso文件。Ubuntu不断升级vbox,这个ISO文件也更新了,但是客户机里面安装的Guest Additions不会自动更新,所以里面还是很老的版本。需要再装一次。

装完后Vega Prime的例程可以运行了。但是植物大战僵尸里面的硬件3D加速还是不能启用:



 查看了vbox的手册,有这样一段
For Direct3D support in Windows guests to work, the Guest Additions must be installed in Windows "safe mode". Press F8 when the Windows guest is booting and select "Safe mode", then install the Guest Additions. Otherwise Windows' file protection mechanism will interfere with the replacement DLLs installed by VirtualBox and keep restoring the original Windows system DLLs.
原来要在安全模式下装Guest Additions:

 

这样装过之后,植物大战僵尸里面还是不能启用3D加速。就装了一个Supertux 0.1.3,帧率在90以上。但是如果选择OpenGL模式就会崩溃掉:

这至少说明Direct 3D功能在Supertux里面用上了,不然FPS能达到90多吗。

看了下植物大战僵尸的说明书,系统要求是DirectX 8或者以上的版本,用的不是OpenGL。不能3D加速就不能吧,vbox的手册里面说对Windows客户机的3D加速还是试验性的,所以就别指望每个程序都能用了。

2011年1月2日星期日

优盘上的Ubuntu

用Ubuntu自带的usb-creator-gtk可以非常方便地在优盘上创建一个系统,用作安装盘或者应急系统使用。用这个优盘从别的电脑里面拷了点东西,然后在自己的Ubuntu桌面上打开这个优盘,系统的主要内容是在casper/filesystem.squashfs这样一个600多MB的大文件里面(Live CD里面也是一样的内容),这是一个squashfs格式的文件。把文件挂载上去,得到一个Linux系统的根目录,但是home里面是空的,没法找到我拷贝进去的文件。必须从这个优盘启动系统,才能看到拷进去的文件。