Sep 10, 2013
Technology最近空气污染很严重,临时写了这个脚本,用来即时生成当前城市的空气质量和温度、湿度等指数。
1. 安装python虚拟运行环境,因为ArchLinux上的python版本是3,需要安装2.x的python,如果你能确认自己机器上的python版本是2,这步可以忽略:
$ mkvirtualenv -p /usr/bin/python2.7 venv2
$ workon venv2
2. 安装beautiful soup和pywapi, pip是python安装环境,BeautifulSoup用来解析html/xml, pywapi是一个用于取得天气数据的库:
$ pip install BeautifulSoup
$ pip install pywapi
3. 输入下面的代码, 将此文件存放为/usr/bin/genhtm.py, 并赋予执行权限:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Using BeautifulSoup for analyse the html file
from BeautifulSoup import BeautifulSoup
import urllib2
# Using pywapi for getting the weather data
import pywapi
import string
# Using django for generating the data
from django.template import Template, Context
from django.conf import settings
settings.configure() # We have to do this to use django templates standalone - see
# http://stackoverflow.com/questions/98135/how-do-i-use-django-templates-without-the-rest-of-django
# Time
from time import gmtime, strftime, localtime
def printweather(city):
print "\nYahoo says: It is " + string.lower(yahoo_result['condition']['text']) + " and " + yahoo_result['condition']['temp'] + " C now in " + city + "!"#ShangHai, MODU!!!!"
print "Yahoo says the humidity is " + string.lower(yahoo_result['atmosphere']['humidity'])
print "Yahoo says the sunrise is " + string.lower(yahoo_result['astronomy']['sunrise'])
print "Yahoo says the sunset is " + string.lower(yahoo_result['astronomy']['sunset'])
pm_array=[2,10]
i = 0
########### Generate the PM2.5 and PM10 Information of NanJing #######
page = urllib2.urlopen("http://222.190.111.117:8023/")
soup = BeautifulSoup(page)
table = soup.find('table', {'class':'table01'})
rows = table.findAll('tr')
for tr in rows:
cols = tr.findAll('td')
if len(cols) >=4 and "PM" in cols[0].text and "1" in cols[1].text:
#print cols[0].contents[0]+' '+cols[0].sub.string+'\t'+cols[2].string
#pm_array[i] = cols[0].contents[0]+' '+cols[0].sub.string+'\t'+cols[2].string
pm_array[i] = cols[2].string
i = i+1
########### Generate the Weather Information from Yahoo Weather#######
#Nanjing
yahoo_result = pywapi.get_weather_from_yahoo('CHXX0099')
word1 = string.lower(yahoo_result['condition']['temp'])
word2 = string.lower(yahoo_result['atmosphere']['humidity'])
# Our template. Could just as easily be stored in a separate file
template = """
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>NanJing,NanJing!!!</h1>
<h2>Temperature</h2>
<p>{{ temper }} C</p>
<h2>Humidity</h2>
<p>{{ humi }} %</p>
<h2>PM10</h2>
<p>{{ pm10 }}</p>
<h2>PM2.5</h2>
<p>{{ pm25 }}</p>
<h2>I Feel as if I will be choked!!!</h2>
<h2>Generated at: </h2>
<p>{{ generated_time }}</p>
</body>
</html>
"""
t = Template(template)
c = Context({"title": "NanJing Weather&PM10/2.5 Data",
#"mystring":"string from code",
"temper" : word1,
"humi" : word2,
"pm10" : pm_array[0],
"pm25" : pm_array[1],
"generated_time" : strftime("%Y-%m-%d %H:%M:%S", localtime()),
})
f = open('/srv/www1/index.html', 'w')
f.write(t.render(c))
f.close()
注意:你需要更改具体的数据源为你自己所在城市的源,上面的文件仅适合于南京。
4. 配置nginx, 使其配置指向我们刚才生成的文件夹/srv/www1/, 由于默认的文件名为index.html,nginx可以正确处理html请求,一个配置例子如下, 具体的配置需要根据自己机器的实际情况来配置:
/etc/nginx/sites-available/default
server {
listen 8009; ## listen for ipv4; this line is default and implied
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
root /srv/www1;
index index.html index.htm;
# Make site accessible from http://localhost/
server_name localhost;
..............
5.\将该python脚本加入到crontab,并设置为每一个小时运行一次:
$ crontab -e
#在文件末尾加入:
*/60 * * * * /usr/bin/genhtml.py
现在你已经拥有了一个可以动态更新相关数据的网页, http://127.0.0.1:8009就可以访问到具体结果,当然如果你配置了本机上的DDNS的话,你可以通过你的DDNS地址来访问本机网页:http://Your_DDNS_Addr:8009/
Sep 10, 2013
Technology此方法适用于主机位于防火墙/路由器后,只有局域网地址的情况。如果在路由器上开启DMZ映射到该主机,则直接可以从公网其他位置访问该主机。
功能:
- 主机开机时会将路由器的公网地址发送到指定邮箱。
- 路由器IP地址发生变化时会将更新后的IP地址发送到指定邮箱。
1. 首先,配置好mutt, 关于mutt的配置,详见:
https://wiki.archlinux.org/index.php/Mutt
2. 保存下面代码到某个文件中,比如/bin/autoip, 而后chmod a+x /bin/autoip:
#!/bin/sh
origip=`curl "http://checkip.dyndns.org/" 2>/dev/null | awk '{print $6}'|cut -d '<' -f1`
echo $origip | mutt -s "ip is" -- kkkttt@gmail.com
while :
do
publicip=`curl "http://checkip.dyndns.org/" 2>/dev/null | awk '{print $6}'|cut -d '<' -f1`
sleep 600
judgeip=`curl "http://checkip.dyndns.org/" 2>/dev/null | awk '{print $6}'|cut -d '<' -f1`
if [ "$publicip" != "$judgeip" ]
then
echo $judgeip | mutt -s "ip changed" -- kkkttt@gmail.com
else
:
fi
done
3. 在/etc/init.d/rc.local中添加一行:
/bin/autoip &
tips:
codeblocks后接lang:bash照样可以激活高亮
Sep 4, 2013
Technologyqemu-system-arm可以直接使用内核用于加载系统。通常情况下我们可以用预编译好的第三方提供的内核来启动系统,然而如果我们需要用到定制的内核,就需要对内核进行编译了。下面的步骤将讲述如何编译出基于arm1136架构的raspberry PI内核。
1. 安装交叉编译链。
ArchLinux中,可以直接从Yaourt仓库里通过“yaourt gnueabihf”查找对应的包,编译的过程不再详述。安装完后,在终端输入arm-(Tab)应该可以看到arm-linux-gnueabihf-开头的编译器。
2. 准备内核源码。
# 从github下载源码
$ git clone https://github.com/raspberrypi/linux.git
# Apply Patch
$ wget http://xecdesign.com/downloads/linux-qemu/linux-arm.patch
$ patch -p1 -d linux/ < linux-arm.patch
3. 配置、编译内核。
# 加载默认配置
$ cd linux
$ make ARCH=arm versatile_defconfig
# 自定义内核
$ make ARCH=arm menuconfig
# 设置编译器
General Setup --->
Cross-compiler tool prefix
(arm-linux-gnueabihf-)
# 选择正确的CPU
System Type --->
[*] Support ARM V6 processor
[*] ARM errata: Invalidation of the Instruction Cache operation can fail
[*] ARM errata: Possible cache data corruption with hit-under-miss enabled
# 激活浮点运算
Floating point emulation --->
[*] VFP-format floating point maths
# 激活ARM EABI
Enable ARM EABI:
Kernel Features --->
[*] Use ARM EABI to compile the kernel
[*] Allow old ABI binaries to run with this kernel
# 激活QEMU磁盘支持
Bus Support --->
[*] PCI Support
Device Drivers --->
SCSI Device Support --->
[*] SCSI Device Support
[*] SCSI Disk Support
[*] SCSI CDROM support
[*] SCSI low-lever drivers --->
[*] SYM53C8XX Version 2 SCSI support
# 激活devtmpfs
Device Drivers --->
Generic Driver Options--->
[*] Maintain a devtmpfs filesystem to mount at /dev
[*] Automount devtmpfs at /dev, after the kernel mounted the root
# 激活重要的文件系统
Enable the important file systems:
<*> Ext3 journalling file system support
<*> The Extended 4 (ext4) filesystem
# 激活tmpfs
File systems --->
Pseudo filesystems--->
[*] Virtual memory file system support (former shm fs)
# 激活event接口
Device Drivers --->
Input device support--->
[*] Event interface
# 激活/proc/config.gz
General Setup --->
[*] Kernel .config support
[*] Enable access to .config through /proc/config.gz
# 启动时字体配置和LOGO配置
Device Drivers --->
Graphics Support --->
Console display driver support --->
[ ] Select compiled-in fonts
[*] Bootup logo (optional)
现在退出并保存.config
#开始编译内核
$ cd linux
$ make ARCH=arm
$ make ARCH=arm INSTALL_MOD_PATH=../modules modules_install
4. 使用新编译出的内核启动系统
$ cp arch/arm/boot/zImage /Your_Qemu_Directory
$ qemu-system-arm -kernel zImage //Your Options.
使用自定义内核的好处是可以方便的激活某些高阶功能,例如NFS, Netfilter等等,一般情况下,默认提供的内核就已经可以满足我们的需要了。
Sep 4, 2013
Technology我用Qemu来仿真RaspberryPI以便快速测试内核模块的开发。下面是仿真的步骤:
1. 下载镜像文件2013-07-26-wheezy-raspbian.img,并更改其配置使得可以被qemu-system-arm加载:
$ fdisk -l 2013-07-26-wheezy-raspbian.img
Disk 2013-05-25-wheezy-raspbian.img: 1939 MB, 1939865600 bytes, 3788800 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000c7b31
Device Boot Start End Blocks Id System
2013-05-25-wheezy-raspbian.img1 8192 122879 57344 c W95 FAT32 (LBA)
2013-05-25-wheezy-raspbian.img2 122880 3788799 1832960 83 Linux
#从上面可以看到,根文件分区的地址偏移为512*122880=62914560
#更改根分区文件里preload信息:
$ sudo mount ./2013-07-26-wheezy-raspbian.img -o offset=62914560 /mnt3
$ sudo vim /mnt3/etc/ld.so.preload
#注释掉这一行,否则在qemu启动完系统后将自动提示配置rpi而造成系统无法登陆
#/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
$ sudo umount /mnt3
2. 拷贝一个此时的img文件以便将来备用
$ cp 2013-07-26-wheezy-raspbian.img 2.img
3. 配置qemu为bridge网络
qemu启动时需要调用的脚本:
$ cat /etc/qemu-ifup
#!/bin/sh
echo "Executing /etc/qemu-ifup"
echo "Bringing up $1 for bridged mode..."
sudo /usr/bin/ip link set $1 up promisc on
echo "Adding $1 to br0..."
sudo /usr/bin/brctl addif br0 $1
sleep 2
qemu关闭时自动调用的脚本:
$ cat /etc/qemu-ifdown
#!/bin/sh
echo "Executing /etc/qemu-ifdown"
sudo /usr/bin/ip link set $1 down
sudo /usr/bin/brctl delif br0 $1
sudo /usr/bin/ip link delete dev $1
在镜像的当前目录下,创建run-qemu文件:
#!/bin/bash
USERID=$(whoami)
# Get name of newly created TAP device; see https://bbs.archlinux.org/viewtopic.php?pid=1285079#p1285079
precreationg=$(/usr/bin/ip tuntap list | /usr/bin/cut -d: -f1 | /usr/bin/sort)
sudo /usr/bin/ip tuntap add user $USERID mode tap
postcreation=$(/usr/bin/ip tuntap list | /usr/bin/cut -d: -f1 | /usr/bin/sort)
IFACE=$(comm -13 <(echo "$precreationg") <(echo "$postcreation"))
# This line creates a random mac address. The downside is the dhcp server will assign a different ip each time
printf -v macaddr "52:54:%02x:%02x:%02x:%02x" $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff )) $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff ))
# Instead, uncomment and edit this line to set an static mac address. The benefit is that the dhcp server will assign the same ip.
# macaddr='52:54:be:36:42:a9'
qemu-system-arm -net nic,macaddr=$macaddr -net tap,ifname="$IFACE" $*
sudo ip link set dev $IFACE down &> /dev/null
sudo ip tuntap del $IFACE mode tap &> /dev/null
因为tap需要用到tun模块,所以增加tun到自动加载的模块中
$ cat /etc/modules-load.d/tun.conf
# Load tun at boot
tun
添加visudo条目:
Cmnd_Alias QEMU=/usr/bin/ip,/usr/bin/modprobe,/usr/bin/brctl
%kvm ALL=NOPASSWD: QEMU
添加用户到kvm组:
$ usermod -a -G kvm username
4. 启动qemu,使用两个镜像,以调整磁盘大小。
# 增加2G大小给镜像
$ qemu-img resize ./2013-07-26-wheezy-raspbian.img +2G
$ ./run-qemu -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1" -hda ./2.img -hdb ./2013-07-26-wheezy-raspbian.img
进入Qemu后,
$ sudo apt-get install gparted
$ sudo gparted /dev/sdb
调整到自己想要的大小即可。
5. 重新启动后用下列命令启动Qemu:
$ ./run-qemu -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1" -hda ./2013-07-26-wheezy-raspbian.img
使用上列步骤所启动起来的RaspberryPI镜像,具备完整的网络支持和足够的存储空间,而运行速度也令人满意。对比于真实的RaspberryPI板,编译、验证、烧写过程都较为简单,大部分研发工作可以基于这个平台来做。
Sep 3, 2013
TechnologyPogoplug上了debian wheezy后,想配置成VPN服务器,在最后一步配置iptables时发现无法激活NAT表。
显示结果为:
$ iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE
can't initialize iptables table 'NAT': Table does not exist (do you need to insmod?)
解决方法:重新编译NetFilter模块。
下载Linux3.1.10内核并解压到/usr/src
$ make menuconfig
{% img img /images/2013_09_03_12_53_06_868x411.jpg %}
而后:
{% img img /images/2013_09_03_12_54_08_749x362.jpg %}
确保以下选项被激活:
CONFIG_NF_CONNTRACK
CONFIG_NF_CONNTRACK_IPV4
CONFIG_NF_NAT
CONFIG_IP_NF_IPTABLES
而后编译,由于在嵌入式系统上编译速度较慢,所以只是编译目录下对应的模块,其他的则不编:
$ make M=net/netfilter modules # Make all modules in specified dir
$ make M=net/netfilter # Same as 'make M=dir modules'
$ make M=net/netfilter modules_install # Install modules
这样就应该可以了,具体的验证等回家再看。