2009年 08月 的归档
Bash其实也可以做CGI用
标题其实是“废话”。因为,其实稍微熟悉web原理的都知道,理论上,所有可执行的程序/脚本,都可以被server程序(例如apache/mini_httpd/lighttpd/nginx等)调用,只要能够输出HTML,都可以成功。
而这个用bash做CGI的想法,纯属闲着无聊的时候,瞎想出来的。不过有这个想法的,我肯定不是第一人,这里和这里都有类似的描述。
不过,我这个Web From Scratch的过程还颇有点波折,试了蛮久才成功,就在此记录一下。
其实,说白了都是也就一句话:扩展名不能随意取。当然这个只是针对我这个主机的apache来说的,其他的server可能有其他的规则,暂且不做定论。
之前我一直把我的脚本文件名写成index.sh,结果怎么试都不行,后来无意中改成inedx.py(虽然里面还是#!/bin/bash开头的)居然就可以了,于是我就找到原因了,现在我改成个更通用的index.cgi了,哈哈。
另外关于.htaccess,由于自己也是一知半解,就不讨论了,有兴趣的话,可以看看这里,这里只贴下我用到的代码,可以把对此域名的任何路径的请求都让index.cgi来处理。
RewriteEngine on DirectoryIndex index.cgi RewriteCond %{REQUEST_URI} !(index.cgi) RewriteRule ^(.*)$ index.cgi/$1 [L] |
来看看我的bash,就是简单地输出服务器信息:
#!/bin/bash #下面这两行头一定要有,不然可是会引发 500 Internal Server Error 错误的。 echo "Content-type: text/html" echo "" echo "<h1>Bash CGI works!</h1>" env | while read line;do echo "<b>" echo "$line" | cut -d= -f 1 echo "</b>=<i>" echo "$line" | cut -d= -f 2- echo "</i><br>" done |
最近几天,可以点击 http://hzlug.org/abc?xxx=yyy 观察这个脚本运行的效果,以后可以把这个地址做它用,嘿嘿。
可以看到 REDIRECT_URL 和 QUERY_STRING 这两个环境变量分别是路径和参数,这样理论上就可以用一个脚本来完成很复杂的功能了~
至于HZLUG到底会做成什么样子,还请大家多多提意见哦~
用脚本操作剪贴板
有时候,在脚本里操作剪贴板是很有用的,比如,你可以用scrot截屏以后贴到paste,然后把url直接放到剪贴板里,方便与人分享;又比如,你可以在选择了一段不和谐的文字的时候,通过按一个快捷键悄悄地把文字变成base64加密以后的内容发给好友;再比如,复制一个单词或者一段文字,按一个快捷键可以在剪贴板里放置翻译后的结果等等。当然肯定有更多方便的应用等你来发现。
在实现复杂应用之前,我们应该先对linux的剪贴板有个基础的了解,其实,linux(准确地说是带X的GNU/linux操作系统)的剪贴板分为3个:
1. 中键主剪贴板
2. 中键辅剪贴板
3. ctrl+v剪贴板
用过linux的朋友肯定都知道一个很方便的特性:鼠标选中一段文字就相当于windows的“复制”,然后在其他程序里按下鼠标中键就相当于“粘帖”,可以把刚才选中的文字粘帖出来。这个经常会让像我一样的linuxer养成一种习惯,以至于在朋友电脑上偶尔使用的windows的时候,也会经常点中键,却什么也出不来。。。同时,这也造成了linux比较损鼠标中键的现象,因为一般的杂牌鼠标,为了节约成本,鼠标中键的轴只有一端是固定的,所以这个轴很容易断,中键都很脆弱,没按几下会坏掉了,我的几个坏鼠标基本上都是中键不灵。。。
呃。。怎么说到鼠标去了,言归正传,这个用中键粘帖的剪贴板我们暂且称为“中键主剪贴板”,另外还有一个“中键辅剪贴板”,一般用户很少用到,“ctrl+v剪贴板”就无须多解释了,就是和windows一样的那个剪贴板,大家平时可能只把这个当成“正宗”的剪贴板吧。
xsel 是用脚本操作剪贴板时需要用到的命令,xsel同时支持这3个剪贴板,那么我们来看看xsel是如何区分这几个剪贴板的:
-p, –primary 指定操作 中键主剪贴板
-s, –secondary 指定 中键辅剪贴板
-b, –clipboard 指定 ctrl+v剪贴板
-x, –exchange 还可以交换 中键主剪贴板 和 中键辅剪贴板 ,这样辅就可以起到一个中间变量的作用了。
下面看看常用的操作:
-i, –input 从标准输入读入到剪贴板
-a, –append 往剪贴板里添加内容 (PS:我发现当某个剪贴板内容为空的时候,使用这个选项会导致xsel出现段错误,不知道是不是应该去报告bug)
-c, –clear 清除剪贴板的内容
-o, –output 输出剪贴板的内容
于是,有了这些好玩的操作,我本来这个
scrot /tmp/scrop_tmp.png -bcsd 3 -e "echo | upaste -image \$f ; rm \$f" |
贴图脚本就改成了这样了:
scrot /tmp/scrop_tmp.png -bcsd 3 -e "echo | upaste -image \$f | xsel -bi; rm \$f" |
这样帖完图以后,URL就直接在ctrl+v剪贴板里了,发给别人也相当轻松了,哈哈。。(upaste是帖东西到http://paste.ubuntu.org.cn,并返回url的perl脚本)
另外,你可以可以看看 xclip 等其他程序,如果有必要的话,下期再介绍啦,哈哈。
UltraEdit出linux版了
下午,看到toy上说UltraEdit出linux版了,做为一个曾经的UE迷,马上就下载来试了一下。
发现,这个虽然是beta版本,但是已经有较强的可用性了。这个测试版本第一次运行的时候,会弹出提示说可以用到2009年9月1号,到时候肯定还是要交钱的,价格貌似和windows版的一样,截图说话吧:
(点击放大)
用python来收发邮件
由于python的模块很强大,用python来收发邮件,就显得很轻松了。
python不仅有email模块,还有专门处理pop、smtp甚至imap的模块。
下面就来演示一下这几个的用法,先看看怎么用pop3和email模块来收邮件。
>>> import poplib >>> p=poplib.POP3_SSL('pop.gmail.com') #如果服务器不需要启用SSL,那么只需要用 poplib.POP3('xxx.com') 就好了。 >>> p.user('linuxcn.ibot') '+OK send PASS' >>> p.pass_('密码') '+OK Welcome.' >>> p.stat() #统计状态,返回一个元组,第一个表示几封邮件,第二个表示一共几个字节 (2, 4543) >>> p.list() #返回每个邮件的状态 ('+OK 2 messages (4543 bytes)', ['1 3679', '2 864'], 15) >>> p.retr(2) #获取某个邮件的全文,这个邮件就是我自己给另一个测试账号发的邮件,元组里包含了邮件头和邮件的正文。 ('+OK message follows', ['Delivere ...为了排版方便,此处有删节... e--'], 869) >>> mailsrc='\n'.join([l for l in p.retr(2)[1]]) >>> print mailsrc #如果上面还看不出啥的话,这样看应该就明显了。 Delivered-To: linuxcn.ibot@gmail.com Received: by 10.216.47.83 with SMTP id s61cs422102web; Sat, 15 Aug 2009 07:58:32 -0700 (PDT) MIME-Version: 1.0 Received: by 10.114.180.16 with SMTP id c16mr2819847waf.57.1250348310512; Sat, 15 Aug 2009 07:58:30 -0700 (PDT) Date: Sat, 15 Aug 2009 22:58:30 +0800 Message-ID: <ae14629e0908150758n49649527xf326b8c1a60f36bf@mail.gmail.com> Subject: =?UTF-8?B?5rWL6K+V5Li76aKY?= From: LLY <bones7456@gmail.com> To: linuxcn.ibot@gmail.com Content-Type: multipart/alternative; boundary=001636417e2fe4c3a904712f669e --001636417e2fe4c3a904712f669e Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: base64 5rWL6K+V5q2j5paHCg== --001636417e2fe4c3a904712f669e Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64 5rWL6K+V5q2j5paHPGJyPgo= --001636417e2fe4c3a904712f669e-- >>> p.quit() #收完邮件了,理论上是要退出一下的 '+OK Farewell.' >>> import email #源码得到了,现在轮到email模块登场了 >>> e=email.message_from_string(mailsrc) #这个就可以把邮件源码转换成一个email的对象了。 >>> print e['subject'] #这个是编码后的主题 =?UTF-8?B?5rWL6K+V5Li76aKY?= >>> print email.header.decode_header(e['subject'])[0][0] #这个是解码后的主题 测试主题 >>> e.get_payload() #获取当前email的有效部分,可以看到有这个邮件有两个部分,从上面的邮件源码,我们也可以得知,此邮件确实有text/plain 和 text/html 两部分 [<email.message.Message instance at 0xb751102c>, <email.message.Message instance at 0xb751172c>] >>> e.get_payload(0) #获取有效部分的第一个,这个还是一个email对象的实例。 <email.message.Message instance at 0xb751102c> >>> type(e) <type 'instance'> >>> type(e.get_payload(0)) <type 'instance'> >>> import base64 #解码邮件正文还得用上base64模块 >>> print base64.decodestring(e.get_payload(0).get_payload()) #解码正文的第一部分 测试正文 >>> print base64.decodestring(e.get_payload(1).get_payload()) #解码正文的第二部分,是html,看来只多了个br而已,哈哈 测试正文<br> |
当然,上面的例子只是最简单的,复杂的附件什么的,也可以用库里的相关函数一一搞定的。另外,看文档的意思,传了get_payload的第二个参数按理应该能自动调用base64模块解码的,但是不知道为什么,我没有试验成功,只能自己手工解了~
下面,再来看看怎么用smtp发邮件,如果是复杂的邮件,也需要建立一个email对象的实例,把正文/附件等一一放上去就好,但是作为演示,我们就用邮件的源码来发一个纯手工的,哈哈
>>> import smtplib #加载模块 >>> msg='To: linuxcn.ibot@gmail.com\r\nFrom: my@localhost\r\nSubject: test\r\n\r\nthis is msg body\r\n' #邮件的源码 >>> s=smtplib.SMTP('smtp.163.com') #同样这里也有SMTP_SSL,到底用什么要看服务器的设置 >>> s.login('bones7456','密码') #一般都要登录了,才能发邮件,login里提供两个参数,用户名和密码 (235, 'Authentication successful') >>> s.sendmail('bones7456@163.com','linuxcn.ibot@gmail.com',msg) #发送邮件,三个参数分别是 from/to/msg,就这名简单就成功了。。 {} >>> s.quit() (421, 'closing transmission channel') |
就这么几行,一封邮件就发出去了,够简单吧。。。更详细的内容就看官方文档吧~
JSON数据格式简介
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition – December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。
以上摘自JSON官方介绍,这个格式是如此地简单,以至于光看这篇官方文档就可以完全掌握了,而无须其他过多地介绍了。
最初看到这个JSON,是在twitter上,这种小交互量的场景很适合用JSON,比XML更轻巧些。今天,看到新闻,taobao也搞了个开放平台,里面也支持JSON和xml这两种格式,所以我觉得这个格式以后会越来越流行,特发此文关注下。
linux的Magic Key
自从我换成了开源的A卡驱动以后,我的电脑就时不时地崩溃。现象是:突然之间,整个画面就冻结了,鼠标也不能动了,几乎所有的按键也都失效了,ctrl+alt+F1 和 ctrl+alt+backspace 都无效。这种情况一般发生在有不规则形状的窗口出现的时候,比如gnome-osd的透明文字,但也不是很一定的,发生的概率也不高,一般几天才会有一次。我想,要彻底解决的话,也只能等待驱动的改进了。
不过,每次崩溃都强行按电源的话,还是有点心痛的。幸好办法还是有的,因为驱动程序其实也只是一个程序而已,这时候即使驱动死掉了,鼠标键盘不能动,linux内核还是在正常运行的(按理如果我开了sshd的话,其他机器还是能ssh上来的)。而且,内核还是能处理一些键盘事件的,比如本文要说的:Magic System Request Key
以下按键,一般情况下不建议使用,除非是ctrl+alt+F1都失效了,才用。
使用Magic SysRq key的前提是CONFIG_MAGIC_SYSRQ这个内核选项被打开,并且没有在/proc/sys/kernel/sysrq里禁用掉,也就是 cat 这个文件的时候,出来的是 1 (或其他某些非0值)。其实这两个条件,在一般的linux发行版里都是满足的。下面就来介绍一下几个键的具体作用,其中SysRq指的是右上角的“Print Screen”键。
ALT-SysRq-b 立即重启系统,不卸载分区和同步文件。
ALT-SysRq-c 调用kexec内核函数来重启,可以生成个crashdump。
ALT-SysRq-d 显示所有的“锁”,如果开了X的话,估计基本看不到。
ALT-SysRq-e 给除了init以外的所有进程发送SIGTERM信号,可以试图正常结束所有进程。
ALT-SysRq-f 调用oom_kill函数来干掉占用了很大内存的进程。
ALT-SysRq-g 内核调试相关的(好像新内核已经没了?)。
ALT-SysRq-h 显示其他key的帮助,同样,如果开了X的话,估计基本看不到。
ALT-SysRq-i 给除了init以外的所有进程发送SIGKILL信号。
ALT-SysRq-k 结束当前虚拟终端的所有进程。
ALT-SysRq-l 显示所有活动CPU的栈跟踪信息。
ALT-SysRq-m 显示内存状态。
ALT-SysRq-n
ALT-SysRq-o 可能的话,关机。
ALT-SysRq-p 显示当前的寄存器状态和标志位。
ALT-SysRq-r 关闭键盘的raw模式。
ALT-SysRq-s 同步内存里的数据到硬盘。
ALT-SysRq-t 显示当前的任务信息。
ALT-SysRq-u 以只读模式重新挂载所有分区。
ALT-SysRq-v
ALT-SysRq-w 显示不可中断的任务
ALT-SysRq-x
ALT-SysRq-z
ALT-SysRq-数字键 调整日志输出级别
另外,除了物理的按键以外,其实还可以把某个键的值用root权限写到 /proc/sysrq-trigger 文件里(这个文件是个只写不读的怪文件,哈哈),比如
echo t > /proc/sysrq-trigger,来触发Magic SysRq key。
以上内容可以在内核源码的 Documentation/sysrq.txt 里找到英文原文,但是即便是这个官方文档,也似乎不是每个按键都有效的,可能是某些只有在特定的硬件条件下才有效,又或者文档没更新?
在万一遇到程序崩溃的时候,你可能需要按的键是: ALT-SysRq-r e i s u b 来安全地重启机器~
使用twip架设Twitter API proxy
twip 是yegle的作品,是一个基于php的Twitter API proxy.配置非常简单,也很好用.
我架的proxy地址是http://li2z.cn/t/(已不可用),要使用的话,把你的客户端的Twitter API proxy指向这里就可以了.以我用的twitterfox为例:
vim ~/.mozilla/firefox/*/extensions/twitternotifier@naan.net/components/nsTwitterFox.js |
然后,把第38行左右的行改成:
var TWITTER_API_URL = "http://li2z.cn/t/"; |
再重启一下firefox就可以了.
如果你也有自己的域名和空间(估计要国外的才行),你可以按照原作者的文章架设一个,如果没有并且相信我不会偷你密码的话,也欢迎使用 http://li2z.cn/t/ 让及.艾服.达不留的人忙到手抽筋为止吧~嘿嘿…
PS: 欢迎follow我: @bones7456
gmbox发布0.1版本
好吧~ 今天发布gmbox V0.1版本了.
看看之前的日志,发现离我发第一篇博文的都已经过了近4个月了.
其实,离之前预想的发布日期不知道迟了多少,好在也没对外公布过发布计划,看来我对自己的”懒”还是有自知之明的,哈哈..
呃..还是说说gmbox吧,基本特性是:
- 支持谷歌音乐的”榜单下载”和”搜索下载”,而且,这两者都包含歌曲和专辑.
- 简单的可配置性
- linux系统可以调用mid3iconv自动修改歌曲的ID3信息编码
- 跨平台性,使用python做为核心,可以运行于大部分linux和windows操作系统,理论上mac也可以,没条件测试
- 界面和核心分离,默认有一个使用pygtk的界面,也可以使用命令行方式操作
安装方法:
- linux版本安装法:下载源码包后,解压,可以 sudo ./install -i 安装至系统目录,就可以在菜单选择”应用程序”-“影音”-“google music box”打开GUI界面,或者运行gmbox打开CLI界面. (-u可以卸载干净的.)
- linux版本不安装法: 下载源码包后,解压,直接运行 gmbox/src/mainwin.py 打开GUI界面; 直接运行 gmbox/src/cli.py 打开CLI界面.
- windows版本: 下载自解压包后,解压至任意目录,运行 mainwin.exe 打开GUI界面,运行 cli.exe 打开CLI界面.
使用方法:超简单,谁用谁知道…
已知bug:还蛮多的,比如试听不支持,歌词下载不支持,还有界面太丑等….哦,现在关闭主窗口,后台的下载进程还不会自动关掉的…以后慢慢完善吧.
再来个截图: