2012年11月27日星期二

Nginx的414错误

请求的URI太长了,Nginx给出了414错误。可通过这个参数调整Nginx可接受的URI长度。Nginx配置中,对该server的日志记录在单独的文件中,但出错时日志只记录在默认的日志文件中。应该是请求URI太长了,Nginx还没有处理到HTTP请求的Host头部,所以不知道是哪个虚拟主机。

2012年11月13日星期二

让echo命令不显示空格

Bash里面
echo {a..z}
会显示:
a b c d e f g h i j k l m n o p q r s t u v w x y z
怎么让它不显示空格呢?试了试IFS不管用,在Freenode上问,人说echo本来就是要显示空格的。这在help echo输出的内置帮助中没有说明,但在info echo输出的外部命令手册中有说明。可以用
printf %s {a..z}
不显示空格。如果必须用echo而不显示空格,看似可以用
echo -e '\b'{a..z}
但这只是看起来没有空格,并不是单纯的26个字母的输出。如用rev倒序上面的输出得不到正确结果:
$ echo -e '\b'{a..z} | rev
                         a
cat -e来看:
$ echo -e '\b'{a..c} | cat -e
^Ha ^Hb ^Hc$
$ echo -e '\b'{a..c} | rev | cat -e

c^H b^H a^H$
顺序的时候空格不显示,但是倒序的时候,每次退格到字母下方(除了a)再打印一个空格,所以最后就只剩下a了。

2012年11月12日星期一

查看Django Debug Toolbar

我在本地打开线上staging环境的Django网站,想用Django Debug Toolbar来查看SQL查询的情况。Django Debug Toolbar显示的默认条件settings.DEBUGTrue,并且用户IP在settings.INTERNAL_IPS里面。但是manage.py启动的服务器在日志里不显示IP地址:
 [12/Nov/2012 21:05:35] "GET /releng/ HTTP/1.1" 200 275953
我想从Staging服务器上的Django日志里面看到本地电脑访问时的IP地址,找到了这个ticket,通过修改basehttp.py可显示IP:
[12/Nov/2012 19:22:21] (119.253.xx.xx) "GET /static/css/base.css?v=bc043 HTTP/1.1" 200 9301
然后把这个IP加入INTERNAL_IPS,开启settings.DEBUG即可显示Debug Toolbar了。

其实不用这么麻烦,可以在DEBUG_TOOLBAR_CONFIG里面设置'SHOW_TOOLBAR_CALLBACK'指到对应的函数即可,见Debug Toolbar的文档。

RAR压缩包乱码的处理

别人用邮件发过来的RAR压缩包(必然是Windows下创建的,我用File Roller解压缩后文件名是乱码。应该是Windows下用的GBK编码,而Linux下用的UTF8编码的问题。用Ubuntu里的unrar-nonfree包的unrar命令解压缩没有乱码,而用free版的unrar也会有乱码,可见nonfree版才会正确处理编码。File Roller集成的必然是free的代码,所以也不能正确处理。

鉴于RAR是封闭、私有的文档格式,我就不给File Roller和unrar报告bug了,他们不能处理也很正常。

2012年11月8日星期四

安装Deb包后配置文件找不到

Debuild编译打包了带封禁模块的Nginx Deb包,需要用dpkg命令安装nginx, nginx-common和nginx-full三个包。可是装完后/etc/nginx下只有几个目录,没有配置文件。上次用同样的包在Ubuntu下安装的,一切都正常。

后来发现,是dpkg -i安装时,即使依赖包没有,显示一堆错误,也会安装上去的,但配置过程会失败。大概是中途依赖没满足,安装后nginx-common包里面的conffiles没有得到配置,所以最后/etc/nginx里面没有配置文件。以后用dpkg安装时,一定要确保安装和配置一次成功,才能避免这种陷阱。

2012年10月23日星期二

Eval is evil

PyYAML读取Puppet的YAML文件,会从中提取出一个ruby变量,成为Python的datetime模块定义的datetime对象。转换为JSON时会出错,因为JSON不知道怎么处理datetime对象。

试了用repr先处理这个对象,即可转换为JSON,在Django中处理时再eval,就可原样返回之前的datetime对象。这样做很方便,无需知道对象的具体类型。但是太不安全了,因为没有内容判断,把从文件中得到的任何东西都进行eval。测试的时候可以eval,实际代码中是用datetime类的strftimestrptime函数配对转换的。

2012年10月21日星期日

Django项目的路径设置

一个别人的Django项目,在命令行用manage.py启动是正常的,但在Eclipse里启动后却出错,页面显示找不到django-session表。发现是找不到SQLite数据库文件的原因。可以看出,django-session是Django进程访问的第一个表,以后如果碰到这个错误,那么一定是数据库配置的问题。

新建PyDev Django项目时,会有对话框来设置项目,包括数据库类型和库名。对于目录里已有相关文件的项目,这个设置是无效果的,该设置是为了给新建项目生成settings.py。出错开始,我还以为需要改正在这个对话框提供过的设置,就在项目属性里找相关的设置,但找不到。其实所有Django相关的设置都在settings.py里面。

settings.py里面,SQLite数据库文件是直接写的文件名,这就是个相对路径,相对于Django进程的工作目录,即getcwd(3)的结果。如果不是从项目根目录启动manage.py(假设settings.pymanage.py都在根目录),那就找不到数据库文件,因为在PyDev里面启动Django时,进程工作目录是Eclipse的Workspace所在目录。
所以不要提供相对路径,而应该使用“动态的绝对路径”。在settings.py的开头写入:
import os.path
ROOT = os.path.dirname(os.path.abspath(__file__))
这样ROOT就是settings.py文件所在目录,根据ROOT来指定项目文件的目录,包括SQLite数据库文件、静态文件等,不论从哪里启动项目,文件都可以找到。