I am LAZY bones ? all linux

分类: '经验技巧' 的归档

找回丢失的磁盘空间

经常接触linux,尤其是多人共用的服务器上的linux的朋友,也许会经常遇到这样的问题:
收到一个磁盘告警,说某某分区已经满了,然后登录服务器 df 一看,发现磁盘确实快满了,然后你就想找到具体是哪个目录满了,于是 du -s * 一看,却发现所有子目录的大小总和却和df显示的总已使用磁盘空间对不上,有时候甚至还相差很多,于是就纳闷了:我的磁盘空间去哪了呢?

这里就列一下我所知的3种情况:

  1. 隐藏文件
  2. linux系统把文件名以.(点号)开头的文件视为隐藏文件,而类似bash里*这样的操作符是不会匹配隐藏文件的,所以如果根目录下有个较大的隐藏文件的话,是不会被du -sh * 统计到的,解决办法就是: du -sh .[^.]*

  3. 非空目录被mount
  4. 一般挂载其他分区的时候都是建议mount到一个空目录的,那么如果mount到一个非空的目录,情况会怎么样呢?比如/mnt目录本来里面是有文件的,然后执行了sudo mount /dev/sda6 /mnt。其实这个mount命令完全能正常执行,被mount的分区也能正常访问,只是原先在/mnt里的文件,现在已经访问不到了,包括du也看不到大小了,但是磁盘空间却还是被占着,因为如果你 umount /mnt 以后,原来的文件都还会回来的。

  5. 空洞文件
  6. 一个文件的大小和所占磁盘空间也不一定完全一致,比如某个程序一直打开着一个叫log的文件在写,而中间有人用 > log 命令清除了log的内容,就会产生这样的文件。这里有这种文件的介绍。

上面3种是我所知的,应该还有其他情况,欢迎留言补充。

用RG100A实现ADSL拨号

最近又搬家了,需要重新办理宽带。问了下电信和网通的价格,虽然华数网通便宜很多,但是那句“一分钱,一分货”还真是一点都没错,之前用过才知道网通不是一般的垃圾,详见我以前的牢骚,所以还是办理了电信宽带。
这电信的入户方式和网通不一样,是电话线入户的,也就是说局端接过来的是一个RJ11的水晶头,然后电信会给一个modem,一般的上网方式就是在modem后面接一个无线路由,再用路由拨号。
但是这样显然不够方便,因为我的路由器是淘宝上淘的RG100A-AA,上面是有RJ11接口的,如果能用路由器直接拨号,就可以抛开电信给的modem了,这样会环保很多(至少modem的电源就不需要了)。
然而,我的路由器默认刷的是OpenWRT的固件,这固件是完全开源的,功能非常强大,什么电驴、BT、samba、FTP、print server统统支持,但是唯独不支持adsl拨号。。。查其原因,据说是BCM系列芯片的adsl驱动是dlink享有版权的,并且不开源。想要用adsl功能必须给路由器刷上基于dlink的固件。
了解到这个信息以后,就开始搜索靠谱的dlink固件,最后我用的是这里下载(需注册)的,这个版本有web界面(英文)、有ssh。基本就可以玩了。
下载后在原来的OpenWRT的web界面里直接上传文件,再重启就刷好固件了,这步真是超乎想象的简单。
再次登录,就是dlink的界面了,默认的用户名和密码都是admin,进去以后,就可以进行一堆设置了,诸如wifi的ssid、密码之类的,都是大同小异,唯一值得一提的是ADSL拨号的设置:
要先在’Advanced Setup’里选择’Layer2 Interface’,就是OSI7层模型里的第二层了,下面有个’ATM Interface’,需要add一条记录,add的时候,会让你填两个数值,就是 VPI 和 VCI ,这两个值各地的运营商都会不一样,比如我这里是杭州余杭电信,这两个值是8/35,具体的值可以到网上查或者是打10000询问电信(不知道电信会不会告诉你)。关于ATM层的更多介绍详见这里
‘ATM Interface’ 设置好以后,就可以设置’WAN Service’了,这里需要选择刚刚设置好的ATM设备,比如我这是 ATM0/0_8_35 ,然后下一步就是填个账号和密码之类的,保存就会自动拨上ADSL了,整个过程还是蛮有趣的,还可以顺便学习一下底层的网络知识。

另外,据说已经有人把dlink的adsl模块二进制地移植到了OpenWRT了,并且已经可用了,说不定哪天我就回OpenWRT了,哈哈。

sudo的配置

大家都知道,root权限是linux系统中的最高权限,有了root权限,就可以对系统做任何操作。
但是,很多情况下,这样一个笼统的root权限并不能很好地满足需求,比如,有时候想让系统的某几个用户有装包的权限(就是执行apt-get或者yum什么的),但是不能随便更改其他系统配置;又比如,想让某个用户有杀死指定另外一个用户的进程的权限(比如www用户什么的),但是也不能随便杀其他用户的进程。
这样一来,便有了细化这个“最高权限”的需求了。于是,权限管理的一大利器——sudo——便应运而生了。
可能是由于sudo的需求本来就比较复杂,看我上面说的例子,用口语表达都比较拗口;也可能是有sudo需要的安全级别比一般的程序要高一些。导致sudo的配置,看上去有点凌乱和摸不着北,所以这里稍微解释一下。
首先,sudo的配置文件是 /etc/sudoers,虽然你也可以手工打开、编辑、保存。但还是建议使用visudo命令来编辑。这是因为:

  • 它能够防止多个用户同时修改它
  • 它能进行有限的语法检查
  • 它能避免因权限位出错而不被sudo认可

然后,打开配置文件以后可以看到有这几部分:

  • Host_Alias、User_Alias和Cmnd_Alias,分别是主机、用户和命令的别名。
  • Defaults一些默认的特性,比如默认要不要重设环境变量,重设哪几个环境变量,默认以谁的身份执行等等。
  • 后面就是重头戏了,类似这样的一行:
    root ALL=(ALL) ALL
    其实这行是 user machine=(users) commands 这样的格式,也就是,允许在machine登录的 user 用户以users的身份来执行commands命令。这里的machine、users呵呵commands就可以用Host_Alias、User_Alias和Cmnd_Alias来代替了。
  • %group ALL=(ALL) ALL
    和上面的一样,只不过这个按组来限制权限。

还是用例子来说话吧,接着上面的两个例子。

例1. 让系统的某几个用户有装包的权限(就是执行apt-get或者yum什么的),但是不能随便更改其他系统配置。
做法就是将这几个用户加入某个特殊的组里(当然,如果你愿意也可以一个个用户分别设置,哈),比如建了yumer组,把用户都加进去了,然后sudo的配置加上:
%yumer ALL=/usr/bin/yum

例2. 让某个用户(dev)有杀死指定另外一个用户的进程的权限(比如www用户什么的),但是也不能随便杀其他用户的进程。
配置如下:
## Processes
Cmnd_Alias PROCESSES = /bin/kill, /usr/bin/kill, /usr/bin/killall, /usr/bin/pkill
Defaults:dev runas_default=www
dev ALL=(www) PROCESSES

先把几个命令alias成一个 PROCESSES,然后指定dev用户,有以www用户的名义执行PROCESSES里的程序的权限。
本来,dev用户必须使用 sudo -u www kill 1111 来杀死www用户的1111号进程的,但是加个-u显然麻烦,所以有了一行: Defaults:dev runas_default=www
这行的意思,是让sudo知道,只要是dev用户执行的,默认就是www的身份,而不是一般的root身份。

这里只是通过两个简单的例子介绍了sudo最常用的功能,其实sudo还有很多其他的有趣功能。比如,sudo还可以实时将非法操作检测出来,以多种方式记录到日志里,不只是本地日志,还可以通过http等方式传到别的机器等。更多功能,当然得参见man页了,哈哈。

跨平台共享鼠标键盘

可能有的老GEEK看到标题,会想到synergy,而我今天要介绍的其实是synergy-plus,因为synergy自从2006年以后,就没有更新了,然而它是个开源软件,所以它并不会就此死掉,有人fork了它的代码,并维护了下去,这就是synergy-plus。
synergy-plus是一个跨平台的鼠标键盘共享软件,支持linux、mac、windows,可以用一套鼠标键盘控制多台电脑,实现光标从这个屏幕飞到那个屏幕,哈哈。
我有这个需求,是因为来这个公司上班以后,公司给分了一个台式机,配置还不错,但是预装的是XP。由于我不是很习惯XP,但是工作中又经常要用到,所以就把自己的神舟本也背来了。于是,桌子上就放了俩电脑。本来俩电脑也没啥的,可是最近夏天到了,我的本本键盘越来越热,基本下不去手了。于是就想起以前看到过的synergy来了,没想到最近多了个plus,呵呵。
那就试试plus吧,目前,synergy-plus 1.3.4 版本已经在gentoo的portage里面了,但是看到主页上,最新的版本却是 1.3.5rc 。于是想尝鲜的我,下载了1.3.5版本,却发现linux下的编译过程并不是很顺利。下载的 synergy-plus-1.3.5-rc-Source.tar.gz (md5sum:db8b2c306695a163e7edf696256913fd) 根本没法编译,于是svn了最新的代码,参照这个编译说明,也还是需要修改几个文件,才能编译过去(而且好像没有install的方法)。不过这个应该是由于这段时间代码在转型吧,相信正式发布的时候,会解决所有这些小问题的。
相比之下,windows的安装过程就及其简单了,因为有现成的二进制的包了嘛,不多说。
我的需求,是要让win的机器当server,linux机器当client的(物理上插着鼠标键盘的机器需要是server)。所以参照这个配置文档,简单设置一下,我的如图:

可以看到,只要设置有几个screens,然后再设置screen间的位置关系,就可以了。
在这里要注意的是,screen的名字,最好是各机器的机器名(我这里windows的机器名是 t-liushun,linux的是 LLY),不然名字不同,是有可能被拒绝连接的。
配置完之后,server点一下start按钮,就会缩到托盘等待client的连接了,然后在linux上执行(文件在bin目录下):

./synergyc -f t-liushun

就可以连上了,这时候,你就可以方便地用台式机键盘控制笔记本喽~
有了这个东西,再加上Dropbox同步两边的文件,基本上,就可以把俩电脑合而为一喽。

另外,如果server端是linux的话,就要建立类似如下的配置文件:

section: screens
	LLY:
		switchCorners = none
		switchCornerSize = 0
	t-liushun:
		switchCorners = none
		switchCornerSize = 0
end
section: links
	LLY:
		right = t-liushun
	t-liushun:
		left = LLY
end
section: options
end

然后执行:

./synergys -f --config 配置文件名

窃以为,这种集中在server进行配置,而client只管连到server的理念,也非常地棒~

========update========
发现用这个还能在两台机器间共享剪贴板,哈哈~至少文本内容没问题,不错。

充分利用磁盘空间,打开ext文件系统的保留区块

今天,吼吼来找我说,他的硬盘,有个分区一共有234G,但是只用了222G,就报满了,无法继续使用了。
其实这个问题,我不久前刚看过一下,只要你仔细看 mkfs.ext3 的man page,就可以知道原因了,其中有这么一句:

       -m reserved-blocks-percentage
              Specify the percentage of the filesystem blocks reserved for the
              super-user.   This  avoids  fragmentation, and allows root-owned
              daemons, such as syslogd(8), to continue to  function  correctly
              after non-privileged processes are prevented from writing to the
              filesystem.  The default percentage is 5%.

也就是说,ext文件系统,包括ext2、ext3、ext4都会默认预留5%的磁盘空间,留给root用户维护系统或者记录系统关键日志的时候使用,这也就是导致普通用户无法使用部分磁盘空间的原因了。
我个人觉得,这个选项用在根分区或者/var之类的分区,还是有一定的必要性的。但是如果是/home、/opt或者干脆是/data之类的数据分区,就显得有点多此一举了。而且,现在的磁盘空间越来越大,5%往往会有10多G,都可以存一部高清了。这么多空间浪费了,是不是太可惜了呢?
于是,就去找相关资料,看能可否在不格式化的情况下改变保留区块的大小。
吼吼找到了这个,比我想像得还要简单,甚至都不需要umount分区,就可以进行修改。
具体操作过程如下,已经加了详细注释:

#之前的保留区有 732463 块
lily@LLY:~$ sudo tune2fs -l /dev/sda7 | grep "Reserved block count"
Reserved block count:     732463
#已用空间+可用空间 和 总空间 相比,还少了近3个G
lily@LLY:~$ df
文件系统	         1K-块      已用      可用 已用% 挂载点
/dev/sda7             57677500  47662588   7085060  88% /home
#调整:
lily@LLY:~$ sudo tune2fs -r 25600 /dev/sda7
tune2fs 1.41.9 (22-Aug-2009)
Setting reserved blocks count to 25600
#再来看看空间,哈哈
lily@LLY:~$ df
文件系统	         1K-块      已用      可用 已用% 挂载点
/dev/sda7             57677500  47662584   9912516  83% /home
#确认调整成功
lily@LLY:~$ sudo tune2fs -l /dev/sda7 | grep "Reserved block count"
Reserved block count:     25600

看到了吧?就一眨眼的功夫,我就多了3G多的空间,哈哈。而且我还不是直接完全去掉保留区块呢,也留了百多兆以防不时之需呢,呵呵。
算了一下,吼吼那个3.4T的磁盘阵列,省出来的空间居然比我的整个硬盘都大。嗨。。。

nginx 对某些 User_Agent 进行限速的方法

本文为nginx 禁止某个 User_Agent 的方法的姊妹篇,不知所云的话,建议先看看这文。
由于之前已经将某个特别疯狂的迅雷的User_Agent给封掉了,所以最近一段时间,我的那源服务器也运行地比较稳定,但是今天,Linux Deepin 9.12正式发布了,由于我给Deepin做了一个iso的镜像,所以服务器又经历了一个访问高峰,如下图:

从这里也可以看出Linux Deepin的受欢迎程度,哈哈。
可以看到从11:00以后,100M的带宽就已经被完全撑满了。。。一看日志,大部分又是迅雷干的,但这次迅雷不是用某个特定的UA来访问了,而是各有变化,但是却都包含MSIE,哈哈。
当然IE用户直接访问的话,也会有这个MSIE,但是没办法,为了保全Ubuntu APT-HTTP的合法权益,只能限制一下MSIE了。
但是怎么限制呢?总不能人家用MSIE的连主页面都打不开吧?哈哈,最好的办法就是限速,于是,有了这个配置:

server {
        listen   80;
        server_name  ubuntu.srt.cn;
        access_log  /var/log/nginx/mirror.access.log;
        location / {
                root   /data/mirrors;
                autoindex on;
                index  index.html index.htm;
                if ($http_user_agent ~ "MSIE") {
                        limit_rate 2k;
                }
                if ($http_user_agent ~ "Mozilla/4.0\ \(compatible;\ MSIE\ 6.0;\ Windows\ NT\ 5.1;\ SV1;\ .NET\ CLR\ 1.1.4322;\ .NET\ CLR\ 2.0.50727\)") {
                        return 404;
                }
        }
 
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
                root   /var/www/nginx-default;
        }
}

让我们邪恶的看一下效果,哈哈:
wget的默认UA的时候:

$ wget --no-cache http://u.srt.cn/ubuntu/ls-lR.gz -O /dev/null
--14:08:28--  http://u.srt.cn/ubuntu/ls-lR.gz
           => `/dev/null'
正在解析主机 u.srt.cn... 211.155.227.167
Connecting to u.srt.cn|211.155.227.167|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:8,051,367 (7.7M) [text/plain]
 
100%[====================================>] 8,051,367      6.34M/s             
 
14:08:29 (6.33 MB/s) - `/dev/null' saved [8051367/8051367]

UA里含有MSIE的时候:

$ wget --no-cache --user-agent="Something with MSIE; bla bla" http://u.srt.cn/ubuntu/ls-lR.gz -O /dev/null
--14:07:59--  http://u.srt.cn/ubuntu/ls-lR.gz
           => `/dev/null'
正在解析主机 u.srt.cn... 211.155.227.167
Connecting to u.srt.cn|211.155.227.167|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:8,051,367 (7.7M) [text/plain]
 
 0% [                                     ] 49,152         2.08K/s  ETA 1:02:38

某个该死的特定UA:

$ wget --no-cache --user-agent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)" http://u.srt.cn/ubuntu/ls-lR.gz -O /dev/null
--14:09:22--  http://u.srt.cn/ubuntu/ls-lR.gz
           => `/dev/null'
正在解析主机 u.srt.cn... 211.155.227.167
Connecting to u.srt.cn|211.155.227.167|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 404 Not Found
14:09:22 错误 404:Not Found。

从上图也可以看到,做了这个设置以后,从14:00左右开始,服务器的流量虽然还是比较大,但是已经趋于正常了。
所以,偶尔要从我源里下东西的同学,可以用firefox直接下载,也可以用axel或者wget之类的工具下,但是千万别用IE相关的工具,不然,后果自负,哈哈~

简单的WP备份脚本

现在,写blog的人是越来越多了;这部分人里,自己建站的也越来越多了;又在这部分人里,用WP来建的也越来越多了。
而建过站的人,都知道备份的重要性。但是手工备份又显然太麻烦了,所以我写了这个脚本来自动备份,放cron里以后,基本上就不用去关心什么了,哈哈,不过在加crontab的时候,要注意用户,如果是用root跑,可能会因为读不到当前用户的key而备份失败哦。
条件是你的空间支持ssh登录,并且事先做好了rsa公钥,登录的时候不需要输入密码。
此脚本会生成两个文件,一个是文件的打包,一个是数据库的打包。上脚本吧:

#!/bin/sh
#WP备份脚本
#方便地备份wordpress的文件及数据库(限mysql)
#作者: bones7456
 
#需要事先设置好这个HOST的rsa key 不然无法用ssh登录
HOST="gnometwe@li2z.cn"
#远程的WP文件所在目录,此目录下要有 wp-config.php
REMOTE_PATH="www/li2z"
#本地保存目录(最好是绝对路径),留空为当前目录
LOCAL_PATH="/home/lily/li2z.backup"
#备份文件的前缀,默认自动按时间生成
PRE=`date +%F-%H-%M-%S`
 
[ -z $LOCAL_PATH ] || cd $LOCAL_PATH
#先备份文件
ssh $HOST "cd $REMOTE_PATH; tar cf - -X exclude ." | gzip > $PRE.tar.gz
#从文件取得数据库信息
tar zxvf $PRE.tar.gz ./wp-config.php
if [ -f wp-config.php ];then
    DB_NAME=`grep "^define('DB_NAME'" wp-config.php | cut -d\' -f 4`
    DB_USER=`grep "^define('DB_USER'" wp-config.php | cut -d\' -f 4`
    DB_PASSWORD=`grep "^define('DB_PASSWORD'" wp-config.php | cut -d\' -f 4`
    rm wp-config.php
else
    echo "Something wrong ..."
    exit 1
fi
#再备份数据库
ssh $HOST mysqldump -u${DB_USER} -p${DB_PASSWORD} $DB_NAME | gzip > $PRE.sql.gz
#这个可选,删除15天前的备份文件
#要打开的话,记得建个专门的目录存放备份,以免误删其他文件
#find . -maxdepth 1 -name "*.gz" -mtime +15 -exec rm {} \;

PS: 稍作修改应该也可以用于非WP的blog系统。

在ubuntu下架设rsync和ftp服务

还是因为我的那个ubuntu源,之前只能以http方式访问,看到很多源也同时提供ftp和rsync的访问方式,我也就学着架设了一个。

先说说ftp方式,这个比较简单,参照官方源,我用的也是vsftpd。这个在ubuntu下几乎是不用配置就可以跑了。大致就是:

sudo apt-get install vsftpd         #安装vsftpd,会自动建立ftp用户,家目录默认是 /home/ftp
sudo usermod -d /data/mirrors ftp   #将ftp的家目录改成你数据所在的目录,人家访问的时候就可以读到这个目录的内容了
sudo /etc/init.d/vsftpd restart     #重启安装的时候就默认启动的vsftpd

这样就完全可以了,如果你还想修改一下人家登录的时候的欢迎信息的话,编辑 /etc/vsftpd.conf ,将里面的 ftpd_banner= 解除注释,并将你要的信息填在后面。
其实这个配置文件还有很多其他选项可以修改,诸如是否允许匿名登录、写权限之类的,需要的话,自己 man vsftpd.conf 好了。

再说说rsync的服务端配置,我发现网上的那些中文教程用在ubuntu下都是会有问题的。
在ubuntu下,这个rsync的服务端和客户端似乎是一个东西,也就是没有rsyncd这个包了,所以也就不需要安装额外的包了,只需简单配置一下,并启动就可以了。
参照 man rsyncd.conf 的提示
建立一个 /etc/rsyncd.conf 文件,内容如下:

motd file = /etc/rsyncd.motd
pid file = /var/run/rsyncd.pid
[ubuntu]
comment = Hangzhou srt ubuntu mirror
path = /data/mirrors/ubuntu
max connections = 3
log file = /var/log/rsyncd.log

其中 motd file 应该是可选的,如果写上了,就需要再建立一个 /etc/rsyncd.motd 的文本,写入欢迎信息,有空的话,还可以搞个帅帅的ASCII art哦。
上面的两行是全局的配置,下面中括号里的是模块名,以下的配置都是模块级的。可以同时指定多个模块。
配置好了以后,执行

sudo /etc/init.d/rsync start

rsync应该就启动了,另外可以在 sysv-rc-conf 里确保启动的时候就开启了rsync服务。

现在也可以通过以下方式访问SRT ubuntu mirror了:
rsync://ubuntu.srt.cn/ubuntu
ftp://ubuntu.srt.cn/ubuntu/

linux真的很安全么?

写这篇文章是因为看到了cnbeta上最近接二连三地出现类似这篇的文章。
虽然我还是认为此文的作者多少还是有点标题党,因为那个 ./a 其实可以是任何东西,这样就说是“一个命令”也太无聊了点。但是我在公司的RHEL4的服务器上试验了之后,确实可以非法提升权限。不免有点担忧。
于是我顺藤摸瓜,在那个提供hack代码的网站上不费吹灰之力,就找到了3个能非法提升root权限的程序,而且这几个程序是一周内公布的,所以相信真要找的话,还能找到很多,何况还有人家未公布的呢?
不过大家也不用太担心,这些程序都有个共同点,见到的最厉害也只能危及2.6.27的内核,而现在的内核都是 2.6.30/31 的时代了。
但是,我公司的2.6.9-55.ELsmp内核的EHRL4服务器就遭殃了,3个程序都中招了,这就说明了保持更新的重要性。一般这种服务器更新都会比较谨慎,有时候甚至无人去管理更新的事情,而且大多都是开着ssh的,这样的linux其实一点都不安全,我就见过一台服务器,老出这样那样的怪问题,最后我去看的时候,大部分/bin和/usr/bin下的常用可执行文件都已经被修改过了,文件的时间也都是一样的,而且正是这个时间开始才反常的。究其原因,正是因为这台公网IP的机器开着SSH,而且root密码还是无敌的“123456”。。。这样,即使那机器本身没有什么重要的文件,一旦被攻陷,损失和麻烦还是不少的,更何况局域网的其他机器也会受到牵连。
在这里,有必要给大家几点建议,做到以下几点linux才能真正安全一些

  • 提高安全意识,不要认为装了linux就可以高枕无忧了,安不安全其实还得靠人。我觉得这点正是最重要的。
  • 如果非得开ssh,一定要装上denyhosts(不知道为什么这个也要墙掉,无语了),denyhosts可以帮你有效地避免被ssh暴力破解。
  • 最好像ubuntu默认的一样,禁用root账号,不然的话,至少禁止root直接ssh登录,因为人家在不知道你用户名的情况下,一般的都是用root来暴力破解的
  • 不要使用弱密码,这点似乎总有人会犯错。。。
  • 始终保持更新,可以避免上面说到的情况。
  • 谨慎执行来历不明的二进制文件,尤其是需要sudo的。开源的才是最安全的。
  • 不要贪图方便,时不时大面积地 chmod -R +x xxxx ,尤其不能 chmod -R 777 xxxx

先这么多了,有其他再补充。。。

gentoo也可以提示未安装的命令

用ubuntu的时候,如果你在命令行里输入一个未安装的命令,bash会给出很人性化的提示,让你先安装xxx软件包,比如:

程序 'xxx' 尚未安装。  您可以通过输入以下命令安装:
sudo apt-get install xxx

其实gentoo下也是可以做类似提示的.
gentoo早就已经默认是 bash 4.x 了,这个版本的bash,在找不到命令的时候,会试着调用 command_not_found_handle 这个函数,也就是说,只要你在什么地方定义了这个函数,就可以实现人性化的提示.再联想到之前我整的e-file,一切都是这么简单,哈哈~
在 ~/.bashrc 里加上如下几行:

if echo "`uname -a`" | grep gentoo >/dev/null ; then
	#由于我的.bashrc是ubuntu和gentoo共用的,所以这里还有些gentoo特有的alias...下面几行才是关键.
	command_not_found_handle () {
		echo "-bash: $1: command not found" >&2
		e-file $1 >&2
	}
else
	#ubuntu的alias....
fi

当然,这之前肯定要先安装e-file,如果你已经加了gentoo-china的overlay,可以直接 emerge e-file
最终效果贴个图(我是gnome,没装kdevelop):
command_not_found_handle效果图