一个纯bashell的http server

其是这个脚本早就写出来了,已经用了一年。现在怕回头自己都忘记了,把它总结一下。

这个http server非常强大,可以说支持任何脚本语言,什么php,python,java,只要能在Linux shell里面调用的都可以。下面是实现方式。

首先是一个接受request和处理请求并返回给客户端的脚本:

#!/bin/bash
base=/data
read request

while /bin/true; do
read header
[ "$header" == $'\r' ] && break;
done

url=”${request#GET }”
url=”${url% HTTP/*}”
query=”${url#*\?}”
url=”${url%%\?*}”

if [ $url == "/" ]; then
url=”/index.html”
fi

filename=”$base$url”

if [ "$query" != "$url" -a -x "$filename" ]; then
echo -e “HTTP/1.1 200 OK\r”
echo -e “Content-Type: bin\r”
echo -e “\r”
export QUERY_STRING=$query
“$filename”
echo -e “\r”
elif [ -f "$filename" ]; then
echo -e “HTTP/1.1 200 OK\r”
echo -e “Content-Type: `/usr/bin/file -bi \”$filename\”`\r”
echo -e “\r”
cat “$filename”
echo -e “\r”
else
echo -e “HTTP/1.1 404 Not Found\r”
echo -e “Content-Type: text/html\r”
echo -e “\r”
echo -e “404 Not Found\r”
echo -e “Not Found
The requested resource was not found\r”
echo -e “\r”
fi

相信含义不解释了,非常非常简单,相信是一目了然了。

接下来定义所有指向80端口的请求都交由这个脚本来处理,需要在/etc/xinetd.d目录中建立一个名为http的文件:

# default: off
# description: The http service can response any\
# request come from 80 port and response to client
service http
{
disable = no
port = 80
socket_type = stream
protocol = tcp
wait = no
user = root
server = /usr/local/bin/zqweb.sh
}

仅此而已。

一个civicrm的bug以及work around

最近在帮同心慈善会实施他们的IT系统,也似乎成了国内第一个用civicrm来实施慈善项目的人。恩~主要是海涛同学。我只负责技术支持和顾问而已了。

估计是因为之前civicrm很好有非英语国家的人用,所以在使用中还是发现了一些问题的。例如刚开始的界面中文问题,可喜的是已经在免费午餐IT小组各位同仁的努力下完成了整个软件的汉化了。这两天又碰到一个中文输入的问题。

问题是这样的,在创建自定义数据组和自定义数据的时候,发现如果名字定义为中文,那只能插入一个数据,之后的数据插入总会报告数据已经存在的错误。仔细分析了一下PHP的代码,发现了问题的所在,但是PHP实在是不灵。所以只是提供了一个简陋的work around并且去civicrm的开发者论坛上发了一贴:http://forum.civicrm.org/index.php/topic,22276.0.html  希望他们能够解决这个问题。

这里我也记录一下我的work around,以便有其他同学遇到了以后可以作为参考。我就直接把我论坛上的帖子内容贴上了,就懒得翻译了再~

In the munge method of /Utils/String.php,  there is a line:
$name = preg_replace(‘/\s+|\W+/’, $char, trim($name) );
But if the $name is a Chinese string, the return value of preg_replace always be ‘_’ regardless what the exact value of $name is.

I worked around this problem by add following lines:
$oldName = $name;
$name = preg_replace(‘/\s+|\W+/’, $char, trim($name) );
if ( $name==’_’ ) $name = $oldName;

这个问题,各位PHP programmer有什么好的思路?

Linode VPS招合租

Linode的VPS服务已经用了一年,相比之前dreamhost的服务相比,真的是好太多了。独立IP,不必为别人的愤青买单。之前担心的有限网络流量和硬盘空间其实根本不是问题。

所以目前准备继续下一年的Linode续费。目前是5个朋友一起租的,基本上大家都是在跑wordpress。但是各位根本不是什么名人,之前每个月带宽才用到限额的5%不到。考虑到不要浪费资源,现在想问问各位朋友们有没有想一起加入我们这个队伍一起合租的。

我简单介绍一下目前的情况,之前参加的是Linode的512 program:

费用是年付,有10%的折扣,就是一年要$215.46。目前系统装的是centOS,跑着几个wordpress,我这个blog就是跑在它上面的,你可以看看速度怎么样。说实话,这个速度在国外的主机里面算是不错的了,当然跟国内的不能比。不过稳定性绝对一流。从来没有出现过宕机什么的现象。我用过国内的rashost,这个速度快是快,但是确实是三天两头宕机啊。

下面一些目前的CPU和网络使用状况:

硬盘是一共16G,目前还剩下4.5G。我觉得这个可能会有些问题,如果人多了不够用可以再额外买一些。

上面就是一些现状了。有想了解更详细的可以再找我。

下面是想对一起合租的朋友的要求:

1. 必须是我熟悉的朋友。

2. 不要想在这个机器上放大访问量、大运算量的程序。

3. 原则上费用大家共担,但是如果你的程序出现额外的大量用户访问或者消耗了大量带宽以至于别人都不够用了,那你就得自己掏钱扩容了。

4. 有问题大家协商解决。

有意想一起玩的朋友尽快联系我吧,这个是需要8月1日续费,我会在这天先把钱付了。

在Linux上的Andorid模拟器中安装apk软件

最近想入手一个Andorid手机,先在机器上装了个Andord SDK和模拟器玩玩。想在模拟器上装个软件,却发现网上找到的资料都是windows上的。虽然Linux上面的大体相同吧,却也有细微差别。所以记录一下。事先声明一下,我的笔记本用的是Ubuntu 10.10。这个系统真的很好用。

1. 准备Andord SDK

Linux上的Andorid SDK下载下来后可以直接解压缩使用。具体下载和安装步骤去看官方文档,这里就不详细说了。就给一个官方地址。因为伟大的GFW,这个地址必须翻墙才能上。

2. 启动SDK Manager创建一个新的AVD(Andorid虚拟设备)

3. 启动模拟器

qi@qi-ThinkPad-T60p:~/tools/android-sdk-linux_86/tools$ ./emulator -avd zq

这里的-avd参数指定需要启动的是哪个模拟器,我这里的zq就是刚才第二步里面创建的那个模拟器了。

4. 安装apk软件

跟windows上一样,linux上也是用adb来安装,但是不同于windows,这个命令的位置是在platform-tools而不是tools。

qi@qi-ThinkPad-T60p:~/tools/android-sdk-linux_86/platform-tools$ ./adb install /tmp/aa.apk
992 KB/s (326241 bytes in 0.321s)
pkg: /data/local/tmp/aa.apk
Success
恩,这样就结束了。确实很简单。安装上以后我发现软件里面的广告显示都很正常。有意思。

重启nginx

今天发现修改了vhost的配置文件后需要重启nginx才可以生效。重启方式为:
/usr/local/nginx/sbin/nginx -s reload

VPS下WP的Twitter plugin不能post的问题

刚才发现在在我的WP中的Twitter Plugin里不能post,错误信息如下:
Warning: main() [function.main]: php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution in /xxxxx on line xxx
搜索后发现是DNS解析的问题,看了好几个国外的帖子也没能找到解决方案。其实解决方案很简单,一试之下就解决了这个问题:
在/etc/hosts下加入本机IP与域名。例如:
=============================
127.0.0.1 localhost
173.230.148.77 www.faquir.net
=============================
需要注意的是,IP跟名称之间用Tab键隔开。
按说通过DNS完全就可以通过域名来获取IP了啊,不知道PHP里面是怎么一个机制。先不管了,先知其然好了,放着所以然到以后再追究。

在linode上配置web+PHP应用环境

    我估计大部分人的vps的主要任务,是跑wordpress,就像我一样。

    所以web server跟php的应用环境应该就是配好了域名之后第二件必须要做的事情了。web server的选择实在太多,老牌的比如apache,恐怕依然是用户最多的环境。不过貌似各位使用vps的前辈用的更多的却是Nginx这个似乎并不出名的web server。对于为何要选择这个,用一句话来说,就是性能优异。相比apache,Nginx更能充分利用vps的有限资源做出更多的事情。少花钱多办事,就是选择这种架构的主要原因了。这种架构的具体介绍可以参见这里

    网上已经有人提供了LNMP的所谓一键安装脚本。我觉得这个东西非常好,集成安装各种软件,简单易用,节省时间。但是依然,有一些事情需要注意。

    如同我的办公环境一样,最开始我自然就安装了Ubuntu。后来当我试图用Licess的这个脚本来安装环境的时候才发现,这个东西的最新版本(LNMP 0.4)目前是不支持Ubuntu的。鉴于最近正好处于公司项目的release阶段,不必要的折腾就省了吧,直接换到CentOS。回想过去,这个系统我也曾经用过挺长一段时间,算怀旧吧。

    安装可以直接按照lnmp脚本的安装说明来做。整个过程基本不会有什么意外情况。所以这个过程就不详细说了。

    接下来就是配置虚拟主机了。按照安装说明里的介绍,是可以直接执行vhost.sh,按照向导说明一步一步来做就可以了。不过这里我需要说明的是,这里虚拟主机绑定的域名,之前要在DNS管理里面事先设置好。并且,貌似linode给每个虚拟机分的ip都是通过dhcp服务,这种服务我们知道,搞不好哪天重启之后你的ip就换了,到时候所有域名均不work,那就绝对杯具了。所以,我们还需要设定我们目前的ip为系统的静态ip,具体的设置方法可以参考这里。注意在centos里面只设置ip是不行的,还需要把dns也设置上。不然在你的centos里面是不能以域名的方式访问其他网站的。

    使用vhost.sh建立的虚拟主机,目录都会位于/usr/wwwroot/xxxxx. 如果是从其他机器上把wordpress或者其他文件拷过来,就可能用到scp命令了,这个命令可以通过ssh的方式从其他系统上把文件复制过来,复制文件的命令为:

scp user@www.xxxxx.com:/xxx/xxx/xxx .

需要注意的是,文件的owner一定要设置成www,否则在访问的时候会出现权限问题。设置了虚拟主机后,虚拟主机的配置文件会放在 “/usr/local/nginx/conf/vhost”目录里面。如果需要对其进行修改,可以直接进入这个目录修改相应的配置文件。例如在开始的时候我们设置了虚拟主机对应的域名是www.faquir.net, 但是实际上我们也需要 faquir.net 也可以访问,那就可以修改这里面的配置文件www.faquir.net.conf,在server_name后面,加上faquir.net,使其成为:

server_name www.faquir.net faquir.net;

随手记录了这些,可能下篇文章会总结一下wordpress的搬家过程吧。

在Linode中设置DNS

搬家到Linode上后需要做的第一件事就是把之前的域名转过来。

其具体做法是这样的:

1. 登录linode.com,选择最上面的DNS Manager

2. 选择Add a new domain zone

3. 在接下来的表单里,domain name填你的域名,但是这里需要注意的是,如果你想让你的域名能以不带www的方式访问,在这里就一定不要填写以www开头的域名。否则不带www的形式是访问不了的。这里的Type选择Master

4. Continue后,在下面那个表单里填写SOA E-mail地址,注意在下面的IP选择框中一定要选择你的公网IP而不是linode内网的IP。

5. 其他都可以保留默认值,直接save即可。

6. 别忘了把你域名的name server设置成linode的,具体地址在前面第四步里save完了以后那个页面上能看到。

但是好像linode里面即便是公网IP都是DHCP而来的,为了保险起见,我们最好还在系统里面设置一下固定IP,省的哪天一重启发现IP变了。在系统里面设置IP的步骤我这里就不列了,各位可以根据安装的不同的操作系统去google一下。这里我需要强调的是,不仅仅要设置IP,似乎DNS服务器也需要设置。我在linode的ubuntu里发现那个已经默认设置好了,但是在centos里面就得我自己来设置。

下回讲讲怎么配置web,php,mysql环境的吧,主要是用的lnmp一键安装包

TightVNC On Ubuntu

这两天在办公室里修了台破机器装了个Ubuntu 9.1. 不知道最近怎么那么人品大爆发,遇到了不少问题。主要是VNC的事情,客户端连接上去总是有问题。最终换了个TightVNC。

最后的问题是连也能连上去了,多个session也能开了,却发现大写键跟shift键根本不灵。搜了一通发现了一个解决方案,遂记录之以备不测:

The workaround is to include the line "export XKL_XMODMAP_DISABLE=1" in ~/.vnc/xstartup as in

    #!/bin/sh

    xrdb $HOME/.Xresources
    xsetroot -solid grey
    #x-terminal-emulator -geometry 80×24+10+10 -ls -title “$VNCDESKTOP Desktop” &
    #x-window-manager &
    export XKL_XMODMAP_DISABLE=1
    /etc/X11/Xsession

apparently it has to be before the "/etc/X11/Xsession" line

分享我的网站(wordpress)数据备份脚本

    前两天突然看到一篇文章讲两个Wordpress备份插件。我想实现异地备份功能,而这其中最好的插件貌似也只能把备份数据通过mail形式发到邮箱里。这对于小数据量的备份还可以,但是如果上传目录里的图多了根本就行不通。于是想到我是可以通过shell访问我的站点空间的,那完全可能通过文件传输协议把备份放到其他地方去。

    首先研究的是能不能通过dropbox,写个脚本直接备份文件进dropbox。我参考了《Install Dropbox In An Entirely Text Based Linux Environment》但是没有成功,原因是dreamhost支持的gclib是2.1版本的,而在纯字符操作环境的linux下安装dropbox需要glib2.4:

image

如果空间可以符合要求的话,可以试试这个方案,我个人觉得应该是最好的方案了。联系了dreamhost的客服,说我得自己来编译跟安装glibc。有点麻烦,有时间了再玩这个吧。

    这条路不通,就只能考虑直接通过ftp把备份文件传到我的路由器上了。有个DDWRT就是方便,直接在管理页面上做了端口映射,把上面的FTP服务的21端口暴露在互联网上,这样就可以通过我的dreamhost访问了。不过这样的缺点就是安全性不好。

    然后用下面的脚本实现备份操作。总体来说,备份需要做的工作分成两部分,一是备份数据库,二是备份一些重要文件。

#!/bin/sh
#Define variables
now=`date +%Y%m%d`
sitename="faquir.net"
dbname="zq_blog"
dbhost="mysql.faquir.net"
dbuser="xxxxxx"
dbpass="xxxxxxxxxx"
ftphost=myhome.3322.org
ftpuser=ftpuser
ftppass=ftppassword

#Clean folders
rm -rf ~/backups/$sitename
mkdir ~/backups/$sitename

#Backup database
mysqldump –opt –user=$dbuser –password=$dbpass –host=$dbhost $dbname > ~/backups/$sitename/$dbname.sql

#Package SQL and uploads images
tar czvf ~/backups/$sitename/$sitename.$now.tar.gz ~/$sitename/wp-content/uploads ~/backups/$sitename/$dbname.sql
echo "created file:"$sitename.$now.tar.gz

#upload to router
ping -c 3 $ftphost
if [ "$?" -eq "0" ]
then
ftp -i -n $ftphost<<EOF

user $ftpuser $ftppassword
cd /data/backups/
lcd ~/backups/$sitename
bin
put $sitename.$now.tar.gz
close
bye
EOF
fi

echo "backup finished!!"

    版权没有,大家可以自行修改以适应你的需求。

    之后在dreamhost中设置crontable让这个脚本每天半夜的时候执行。完了就给我的指定邮箱里发邮件。于是每天早上我除了得到我的备份文件外,就可以得到这样一个邮件了:

/home/zhangqi/faquir.net/wp-content/uploads/
/home/zhangqi/faquir.net/wp-content/uploads/2009/
/home/zhangqi/faquir.net/wp-content/uploads/2009/12/
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/australia-150×150.gif
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/australia1-150×150.gif
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/.jpg-150×150.jpg
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/20-150×150.jpg
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/australia1.gif
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/21-300×225.jpg
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/1-300×150.jpg
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/australia-291×300.gif
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/21.jpg
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/.jpg-300×150.jpg
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/20.jpg
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/20-300×275.jpg
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/1-150×150.jpg
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/australia1-291×300.gif
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/australia.gif
/home/zhangqi/faquir.net/wp-content/uploads/2009/11/21-150×150.jpg
/home/zhangqi/backups/faquir.net/faquir_net.sql
created file:abigbird.com.20091203.tar.gz
PING myhome.3322.org (124.64.122.70) 56(84) bytes of data.
64 bytes from 124.64.122.70: icmp_seq=1 ttl=49 time=247 ms
64 bytes from 124.64.122.70: icmp_seq=2 ttl=49 time=228 ms
64 bytes from 124.64.122.70: icmp_seq=3 ttl=49 time=246 ms

— myhome.3322.org ping statistics —
3 packets transmitted, 3 received, 0% packet loss, time 2007ms
rtt min/avg/max/mdev = 228.394/240.844/247.589/8.832 ms
Local directory now /home/zhangqi/backups/faquir.net
backup finished!!

Next Page »