2012年3月

邀请赛----北京游

邀请赛两年一次,有两个软件组,一个DSP组,一个FPGA组。软件组我和醒哥做了一些,不过我不想做windows了,想去做linux。杰哥当时参加的就是FPGA组,他们做的网络行为分析系统,具体干啥的我也说不清楚。大概是linux上面搭平台,网络数据分析。目前连题目的都不知道。。。

- 阅读剩余部分 -

API扫描器小结

不久前,冏哥叫我写一个API的扫描器,具体的要是先的功能就是扫描API,当然是用shell实现。我这个shell语法都有点问题的小青年写的可是够呛人的。下面是有一些语法的问题,我记录下。

小数比较大小


$ echo "2.0>1.2" | bc

如果正确就返回1,否则返回0。

字符串连接


#!/bin/bash
i=1
while read ISBN
do
        echo "$i : $ISBN"
        sed "$id" -i ISBN.txt      # 原本是读取一行删除一行,但shell会解释成id这个变量
#      sed "${i}d" -i ISBN.txt    # 这样才是对的~~~变量连接
        let i++
done < ISBN.txt

[,[[比较区别


[ 就是等价于test,而[[ ]]是[]的升级本版。下面是简单的叙述
[ : 支持 exp1 -a exp2,exp1 -o exp2
[[ : 支持 exp1 || exp2 , exp1 && exp2

post包发送网页并且读取响应


# wgetURL --post-data "name=value"  -o  Log.txt -Oweb.img

-O指定输出文件名web.img

-o将屏幕上的输出重定向到Log.txt

 

 

 

apache虚拟主机配置(壹)

曾经一度困扰我的一个问题就是,对于同一个服务器,上面绑定着几个域名,我们实验室的就是这样。几个哥们的博客地址都指向同一个IP,那么我本地要去访问A域名的时候,DNS会把请求的域名A数据包解析成目标服务器的IP,然后本地再去发送包给DNS解析出来的IP,接着通信就建立。但是不明白的是,假设服务器上有好几个域名,比如是A,B,C。但是DNS解析出来的肯定是一个IP,那么服务器是怎么样把请求的包区分开来是请求哪个域名的呢?这两天配置了下apache的虚拟主机,总算了解了些。

- 阅读剩余部分 -

FIFO管道

写脚本的时候用到FIFO,不是很会,就学习了下。下面是简介:

FIFO也称为有名管道,它是一种文件类型。FIFO简单理解,就是它能把两个不相关的进程联系起来,FIFO就像一个公共通道,解决了不同进程之间的“代沟”。普通的无名管道只能让相关的进程进行沟通(比如父shell和子shell之间)。还是用代码来说明问题好了。

- 阅读剩余部分 -

bash中"["的误区

纠结一段代码好几天,Linux下不会看反汇编,不知道shell里面怎么跑,于是栽了个跟头。

#!/bin/bash

STR1="Hello"
STR2="World"

if [ "$STR1"=="$STR2" ]; then                  #"=="两边没有空格
        echo "$STR1 == $STR2"
else
        echo "$STR1 != $STR2"
fi

if [ "$STR1" == "$STR2" ]; then                #"=="两边有空格
        echo "$STR1 == $STR2"
else
        echo "$STR1 != $STR2"
fi

结果大失所望,第一次竟然输出Hello == World !”==“两边的空格对shell到怎么做了什么?百思不得其解,问了杰哥,杰哥回给我的邮件。

- 阅读剩余部分 -

静态链接库和动态链接库

以前的时候写过这方面的博客,当时写的时候都觉得已经懂了。今天闲着没事干,和咚哥他们去大华校招笔试遇到了这个问题。我突然间发现SDK没写三个月,把Dll都忘记了。回来看了下,复习下。

以前写过程序的装载和链接的博客,那是OS上面比较理论的。实际用函数库的时候主要分为,静态库和动态库,这里就简简单单地介绍下了。

静态库


静态库(Static Libary)就是平时的 .lib 文件,静态库里面包含的是所有的代码和数据,是完整的!程序在编译生成.obj文件后,连接器将.obj文件和.lib文件整合到.exe里面,程序运行时候所需的函数代码和数据都已经在.exe中了,静态库很霸道,不管你愿不愿意,它就一股脑儿把所有需要的东西都给你,所以就没有导出函数这个概念,缺点就是整合出来的产品比较大,而且很不利于下次的升级,每次升级都得把lib文件修改,然后重新编译链接整合出来新的程序,而且静态链接库不能包含其他的链接库,这一点和动态链接库有很大的区别

使用方式:


在生成的.h文件中做如下声明

extern "C" function()......

在调用函数的.cpp文件里面

#include "XXX.h"

#pragma comment(lib,"XXX.lib")

动态链接库


动态链接库是在运行的时候动态加载的,可以人为也可以非人为,看你怎么用,总之就是很灵活。下面直接说调用方式。

1.隐式加载


隐式加载把你的动态链接库的代码生成.lib文件+.dll,隐式加载的时候需要的就是.h,.dll,.lib文件。说的简单点,.dll文件里面是函数的定义和数据,只是一部分,那么声明呢?声明就在.lib,.lib文件就包含了.dll文件中函数的声明和一些其他的数据。奇怪了,为什么上面的静态链接库里面的.lib文件不是涵盖了所有的函数信息吗?我以前百思不得其解,查了下网上的资料,此.lib非彼.lib。若是编译链接你的dll至少输出一个函数的话,.lib文件就当作一种引导函数的输出表来用了,里面包含了函数的“声明”。在隐式加载里面的.lib文件编译链接的时候整合到程序里面,但是dll里面的代码和数据却没有整合进去,让exe文件所占空间更小。但是加载程序加载exe,dll就被加载到内存中了,加载程序先为新的进程创建一个虚拟地址空间,并将可执行模块映射到新进程的地址空间中。加载程序接着解析可执行模块的导入段。对导入段中列出的每个DLL,加载程序会在用户的系统中对该DLL模块进行定位(差不多就是和lib中进行核实),并将该DLL映射到进程的地址空间中。注意,由于DLL模块可以从其它DLL模块中导入函数和变量,因此DLL模块可能有自己的导入段并需要将它所需的DLL模块映射到进程的地址空间中。

详细参考http://www.cnblogs.com/forlina/archive/2011/08/08/2131011.html

隐式加载使用方式:


#include "XXX.h"

#pragma comment(lib,XXX.lib)

并把dll放到环境变量或者执行目录下

2.显示加载


采用LoadLibrary,FreeLibrary来手动加载,这种加载是在程序运行的时候加载所需要的Dll,和隐式链接不一样,显示加载随时可以在需要的时候加载指定的Dll模块,也可以随时卸载。而隐式加载实际上存在一个Dll计数器,当计数器为0的时候系统就自动帮你卸载了。函数会在用户的系统中对DLL的文件映像进行定位,并试图将该文件映像映射到调用进程的地址空间中。LoadLibrary返回的HMODULE表示文件映像被映 射到的虚拟内存地址。  

显示加载使用方式:


只需要Dll即可

详细参考http://www.cnblogs.com/forlina/archive/2011/08/08/2131042.html

 

 

fedora 16 使用LiveCD修复grub2引导--<转>

转自 http://cryinstall.com/?p=121

Mr高 被钟大神忽悠装了Opensuse,然后这俩家伙对装系统的引导项设置不对劲,Opensuse的grub直接装到硬盘的MBR上,

然后华丽丽的把原来Fedora 16的grub2给覆盖了,接着Opensuse又识别不了grub2,…..

现在的孩子都喜欢装系统,win7+fedora,如果先装win7再装fedora,是蛮简单的,如果先装fedora,然后win 7,本文方法也是适用。

 

- 阅读剩余部分 -

pushd,popd,dirs--Bash实现

写了一个bash脚本,实现popd,pushd,dirs功能。下面是代码:
 
[cc lang="c"]
#!/bin/bash
#stack.sh
#实现pushd popd dirs功能

#mypush函数实现pushd命令的功能,每次支持压栈一个目录
#缺省目录是当前目录,所有目录保存在_DIR_STACK变量中,
#以:做为分隔符。
function mypush()
{
REQ="$1" #接受参数1是目录参数
REQ="${REQ:-.}" #如果参数1是空,则
if [ ! -d $REQ ]; then #如果参数是非目录
echo "$REQ is not a directory"
return 1
fi

if cd "$REQ" ; then #切换目
_DIR_STACK="`pwd`:$_DIR_STACK"; #把参数添加到_DIR_STACK变量中
mydirs #显示栈中的目录
else
echo "ERROR : Cannot change to directory $REQ."
return 1
fi

unset REQ
}

function mypopd()
{
_DIR_STACK=$_DIR_STACK
mydirs
TEMP_PATH=`echo $_DIR_STACK | cut -d: -f1` #指定_DIR_STACK中的第一个项(目录)
if [ ! -z "$TEMP_PATH" ]; then #判断目录是否为空,若是空,则说明栈是空
if cd "$TEMP_PATH" ; then
_DIR_STACK=`echo $_DIR_STACK | cut -d: -f1 --complement` #保存除了第一个目录外剩下的目录
else
echo "Error : change directory failed !"
return 1
fi
else
echo "Error : Stack is empty ! "
return 1
fi
}

#mydirs函数是dirs命令的实现代码
function mydirs()
{
OLDIFS="$IFS" #保存原先的分隔符号
IFS=":" #指定分隔符号是:
for i in $_DIR_STACK
do
printf "$i \t" #打印出栈中目录
done
IFS="$OLDIFS"
}
[/cc]
通过$ source stack.sh来执行脚本
mypush [路径] 来进行压栈操作
mydirs 来显示栈中目录项目
mypop 直接压出栈中最上面一个目录

OSPF Guide --<转>

from --  http://www.cisco.com/en/US/tech/tk365/technologies_white_paper09186a0080094e9e.shtml#intro

Introduction


The Open Shortest Path First (OSPF) protocol, defined in RFC 2328 , is an Interior Gateway Protocol used to distribute routing information within a single Autonomous System. This paper examines how OSPF works and how it can be used to design and build large and complicated networks.

- 阅读剩余部分 -

Shell脚本中cd命令使用

在写shell脚本的时候发现cd切换目录的时候无法切换,代码是下面的。
#!/bin/bash #changedir.sh cd /home/firefox pwd
我仔细一想,我执行的时候是./changedir.sh来执行的,这样执行的话终端会产生一个子shell,子shell去执行我的脚本,在子shell中已经切换了目录了,但是子shell一旦执行完,马上退出,子shell中的变量和操作全部都收回。回到终端根本就看不到这个过程的变化。
那么怎么验证上面的猜想呢?看下面的代码
#!/bin/bash #changedir.sh history cd /home/firefox sleep 1 pwd
首先按照 ./changedir.sh执行,这时候终端没有切换目录,history执行的结果是空的,说明子shell里面没有历史命令(这是肯定的)。
然后按照 source changedir.sh执行,这时候就是直接在终端的shell执行脚本了,没有生成子shell,执行的结果就是输出历史命令,并且切换了目录。

RIP Protocol Limitations and Problems--<转>

The simplicity of the Routing Information Protocol is often given as the main reason for its popularity; I certainly have mentioned this enough times in this section. Simplicity is great most of the time, but an unfortunate “price” of simplicity in too many cases is that problems crop up, usually in unusual cases or special situations. And so it is with RIP: the straight-forward distance-vector algorithm and operation mechanism work well most of the time, but they have some important weaknesses. We need to examine these problems to understand both the limitations of RIP and some of the complexities that have been added to the protocol to resolve them.

- 阅读剩余部分 -

打包和压缩Bash实现

用bash写了一个打包和压缩的脚本,代替bzip2和tar的繁琐参数,最好把脚本放到全局环境变量中。
#!/bin/bash #用脚本使用形式 function usage() { echo "usage : `basename $0` [-c|-t|-x] FileName " } #脚本参数含义 function help() { echo "-c 打包并压缩文件" echo "-t 查看压缩文件的内容" echo "-x 解压缩打包文件" } #保证参数多余两个 if [ $# -lt 2 ]; then usage exit fi #先判断参数$1是打包压缩还是解包解压,或者是查看压缩内容 while : do case "$1" in -c) #打包压缩 OPT="-jcvf" #指定参数,支持bzip2压缩 shift #移除第一个参数 for FILE in $@ do tar "$OPT" "$FILE".tar.bz2 $FILE if [ $? -eq 0 ]; then echo "$FILE -->> $FILE.tar.bz2" continue else echo "error" exit 1 fi done exit;; -t) #查看压缩文件内容 OPT="-jtvf" shift for FILE in $@ do tar "$OPT" $FILE done exit 0 ;; -x) #解包解压缩 OPT="-jxvf" shift for FILE in $@ do tar $OPT $FILE done exit 0 ;; *) help exit 1 ;; esac done

Vlan中Trunk封装方式

VLAN是为解决以太网的广播问题和安全性而提出的一种协议。引入VLAN后,各VLAN内的主机跨交换机进行通信。为了标识各数据帧属于哪一个VLAN,需要对数据帧进行打标(tag)封装,即在以太网帧的基础上增加了VLAN头,用VLAN ID把用户划分为更小的工作组,限制不同工作组间的用户二层的访问,每个工作组就是一个虚拟局域网。目前交换机支持的打标封装协议有IEEE802.1Q和ISL。其中IEEE802.1Q是经过IEEE认证的对数据帧附加VLAN识别信息的协议,属于国际标准协议,适用于各个厂商生产的交换机;而ISL是Inter Switch Link的缩写,是Cisco系列交换机支持的一种与IEEE802.1Q类似的协议。两者互不兼容,ISL是Cisco独有的协议,只能用于Cisco网络设备之间的互联。

- 阅读剩余部分 -

统计文本中单词使用频率

#!/bin/bash #统计单词的频率 if [ $# -lt 1 ]; then echo "usage : $0 filename" fi filename=$1 cp $filename $1_backup if [ ! -f $filename ]; then echo "$filename is not a file" fi temp=$1_temp cat $filename | tr '[:punct:]' ' '\ | tr ' ' '\n' | tr 'A-Z' 'a-z' > $temp # 先把文本的中的标点全部替代成空格,然后把每个单词单独一行,全都转化成小写,方便后面的处理,输出到filename_temp文件中 sed -i -E -e '/^$/d' -e '/^[0-9]+/d' $temp # 把filename_temp文件中的空行和字母开头的行删除,用-i写入文件 sort $temp | uniq -c | sort -rn > $1_result.txt #先将sort按照字母排序,uniq对于连续的相同的行只输出一次,sort -r 逆序排序,默认是从小到大,输出结果到result.txt中 rm $temp # 删除临时文件