在LNMP里的Nginx安装Awstats分析日志

运行需要PERL的支持,因为Nginx对PERL支持很弱,只能通过生成Html方式来输出统计。

首先,需要每日切割日志文件。提供个脚本给大家

mv /usr/local/nginx/www.bun5.com.log /usr/local/nginx/logs/access5dft_`date +%Y%m%d`.log

killall –s USR1 nginx #使用USR1参数通知Nginx进程切换日志文件

很简单,两行实现切割。别问我格式,我网上抄来的。太困了,争取最快时间写完。

然后到某开源网wget回来,解压即可。我放到/usr/local/里面了,别问为什么,我习惯。

接下来的内容非常非常重要,大家睁大眼睛看清楚。修改日志配置为以下格式(具体位置在/usr/local/nginx/conf/你的网 址.conf):

log_format www.bun5.com ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” “$http_x_forwarded_for”‘;

行了格式就是上面那样,要问为什么?因为默认格式Awstats不认。o(╯□╰)o

在刚刚解压回来的文件里面的tools找到awstats_configure.pl并执行开始配置。

—–> Check for web server install
Enter full config file path of your Web server.
Example: /etc/httpd/httpd.conf
Example: /usr/local/apache2/conf/httpd.conf
Example: c:\Program files\apache group\apache\conf\httpd.conf
Config file path (‘none’ to skip web server setup):
#> none #因为我们这里用的是 Nginx,所以写 none,跳过。
回车
Your web server config file(s) could not be found.
You will need to setup your web server manually to declare AWStats
script as a CGI, if you want to build reports dynamically.
See AWStats setup documentation (file docs/index.html)
—–> Update model config file ‘/usr/local/awstats/wwwroot/cgi-bin/awstats.model.conf’
File awstats.model.conf updated.
—–> Need to create a new config file ?
Do you want me to build a new AWStats config/profile
file (required if first install) [y/N] ?
#> y #y 创建一个新的统计配置
回 车
—–> Define config file name to create
What is the name of your web site or profile analysis ?
Example: www.mysite.com
Example: demo
Your web site, virtual server or profile name:
#> www.5dft.com #统计网站的域名
回车
—–> Define config file path
In which directory do you plan to store your config file(s) ?
Default: /etc/awstats
Directory path to store config file(s) (Enter for default):
#>
使用默认直接回车,接下来便会出现以下的提示
—-> Add update process inside a scheduler
Sorry, configure.pl does not support automatic add to cron yet.
You can do it manually by adding the following command to your cron:
/usr/local/awstats/wwwroot/cgi-bin/awstats.pl -update -config=www.5dft.com
#回头把该命令填入crontab 按指定时间执行
Or if you have several config files and prefer having only one command:
/usr/local/awstats/tools/awstats_updateall.pl now
Press ENTER to continue… 回车继续

【上面从别的地方摘来的,别问从哪摘,N个网站都这篇文章我哪知道出处?反正我是上面少了一个步骤,少了个回车,其它正常。继续】

接下来就生成了个文件了。我的是在/etc/awstats/awstats.www.5dft.com.conf

在那个文件找到统计的日志文件的路径
LogFile=”/var/log/httpd/mylog.log”
改为
LogFile=”/opt/nginx/logs/access5dft_%YYYY-0%MM-0%DD-0.log

对应上边 Nginx 日志切割程序的所生成的目录存放结构,要注意 Awstats 的年月日格式的跟 Nginx 的写法有所不同。我们现在执行统计的顺序是:
Nginx 产生日志 –> 日志切割 –> Nginx 继续产生日志 –> 另存切割日志 –> 交由Awstats统计 –> 生成结果
在本文中 Awstats 所统计的日志,是已切下来的那部分。也能调转顺序,先统计完了再切。不过这比较容易造成统计的遗漏。配置修改完成后,保存退出。然后我们可以开始试一下手 动执行。

先执行日志切割脚本 logcron.sh 把 Nginx 的日志切下来。
然后执行 Awstats 日志更新程序开始统计分析。
./logcron.sh

/usr/local/awstats/wwwroot/cgi-bin/awstats.pl -update -config=www.5dft.com

看到几行类似

Found 0 dropped records,
Found 0 corrupted records,
Found 0 old records,
Found 120 new qualified records.

就是成功了。如果没有的话是缺少一个/var/lib什么什么的,mkdir一下就可以。我发现网上教程都少了这一步,耽误小白啊。o(╯□╰)o 还好我是大白,很快解决。继续。

那么我们就必须建个文件夹来放文件咯。放在网站里面方便看。
省略建文件夹步骤,继续。

/usr/local/awstats/tools/awstats_buildstaticpages.pl -update -config=www.bun5.com -lang=cn -dir=/home/wwwroot/oc86.com/xxx -awstatsprog=/usr/local/awstats/wwwroot/cgi-bin/awstats.pl

上面的命令我不查资料还真不知道。awstats_buildstaticpages.pl是生成静态页面的。后面指定更新,后面语言CN,后面指 定生成静态的目录,后面awstats.pl是Awstats 日志更新程序路径。

请注意上面的命令是一行的,切勿分割或者别的什么的。
把那个和分割日志的放进crontab即可完成任务。

好了,到此任务基本完成。剩下的生成的文件要怎么加密就是你的问题了。我是懒虫,试了几次500之后我就直接改个复杂的文件夹名就完事了。但是别塞 进robot,否则…嘿嘿,别人一看就知道了。

漫谈C语言及如何学习C语言

转自:http://sunxiunan.com/?p=1661

云风最近写了一篇博客《C语言的前世今生》。作为长期使用C语言开发网络游戏服务器的程序员,云风是有理由写这样一篇文字,不过还是感觉谈的不够深入,C语言在业界使用的现状没有怎么描写,有些意犹未尽。

在这里想比较系统的谈谈个人对C语言学习方式方法的理解。分别按照书籍、实验环境搭建、网络资源来分别介绍,希望能写的比较完整全面一些,给想学习C语言的朋友一个有价值的参考。

为什么要学习C语言?

为什么要学习、使用C语言?为什么要学习一个可能比自己都岁数大的编程语言?

我在前面如何学习编程语言的博客文章http://sunxiunan.com/?p=1597 里提到,选择一门编程语言,“为什么而学”这个目的是最重要的,目的不明确就没法学好。这也是为什么很多学生朋友在大学里必修C语言却觉得没学明白的原 因。因为学习的目的不明确,学习当然也没有动力。还有一个原因是C语言是工程实践性很强的语言,它不是来自某个研究所某个大学学院,而是实实在在从项目需 要中产生,伴随着Unix的兴起而流行,语义简明清晰,功能强大而不臃肿,简洁而又不过分简单,实在是居家旅行工作学习必备之良友。

C语言相比C++的优点之一就是最小惊讶原则,一是一二是二,不会在私底下产生一些莫名其妙的额外产物。用C++做个例子,比如这样一个函数原型 void PassWithClassValue(COneClass clsParam1),稍微了解C++的朋友都会知道,如果你没有实现COneClass的拷贝构造函数,编译器会好心的帮你实现一个,而且在调用这个函 数PassWithClassValue的时候,偷偷地调用拷贝构造函数产生一个临时对象作为参数传递,对于某些情况,比如编写操作系统这类必须优化性能 的情景下,这些自以为是的东西是非常邪恶的事情。

C语言本身只提供必要的语言特性,其它复杂一点功能如文件处理、数学计算等等都以库函数方式提供,甚至连malloc、free这种“必须有”的功 能,也是以标准库函数的方式提供,而不是作为C语言核心出现。在伟大的著名的无所不包的《K&R》开头部分就提到了,for其实可以通过 while来完成,只不过for可以写的更简洁,言外之意,对于C语言for其实不是必要的。跑题一点说,在其它程序语言中Lua可以说继承了C语言简洁 的设计哲学,甚至连continue这种几乎必备的关键字都一直拒绝加入,在Lua的maillist以及wiki里都提到过continue这个问 题,Lua语言维护者认为continue对于Lua而言不是必要的,也不考虑在后续版本中添加这个关键字。这种简洁哲学也让C语言的可移植性、便携性特 别优秀,也使得很多嵌入式系统依然使用C语言作为主要编程工作语言。

Java语言有一个口号:“一次编写,处处运行”,就是跨平台这个噱头。实际上C语言从早期开始就几乎达到了“一次编写,处处编译”,在ANSI在 1989年统一了C语言标准以后(称之为C89),只要特定平台上的编译器完整实现了C89标准,而且你的代码没有使用某些特殊的扩展(GCC以及微软都 有自己的编译器特定扩展),那么代码一定可以编译通过,再实现一下操作系统相关的函数库,C语言的移植就是很简单的事情。可以用Lua作为例子,Lua本 身是完全遵循C89标准,没有使用任何特定扩展,这也保证了有C语言编译器的平台,都可以编译使用Lua。可以编译运行C语言的硬件平台可以从A排到Z, 真是非常有意思的事情。

C语言也是一个比较少见的应用领域极为广泛的语言。比如编写操作系统这种高难问题,只有C++、汇编语言可以做到。C语言可以编写服务器端软件如 Apache、Nginx,或者编写GUI程序,如GTK。大多数程序语言的第一版是通过C语言实现,借助前面提到的“一次编写处处编译”,最大的保证了 这些程序语言的可移植性。在Web开发领域,C语言的应用相对较少,这也是一种取舍的结果,Web开发需要使用PHP、Ruby、Python这样的动态 语言,可以快速上线快速修改,可以最大程度满足用户时时变化的需求,这也是C语言的弱项。如果把程序语言的应用领域从硬件到管理软件、Web程序做一个很 粗略从下到上的排列,C语言适合领域是比较底层靠近硬件的部分,而新兴语言比较偏重于高层管理或者Web开发这种相对贴近最终用户的领域。比较流行的混合 开发模式是使用C语言编写底层高性能部分代码或后台服务器代码,而使用动态语言如Python做前端开发,充分发挥它们各自的优势力量。

提到C语言的缺点,常常是它缺少这种或者那种特性,比如有人建议加入GC,有人建议加入并行或者并发支持,有人提到没有一个比较完整的类似C++的 异常策略。这些特性有的可以通过引入第三方库来实现,但C语言的设计哲学其实决定了它不会像C++那样“非常强大”。即使引入了某些人期望的特性,依然会 是某些人喜欢某些人不喜欢的情形,现在的功能对于C语言应用领域来说已经够用,其它特性可以通过特定程序语言实现,并且通过C API与C语言编写的程序进行交互。任何一个工匠都不可能只使用一个工具完成他的工作,不同工具结合起来才能更快更好的完成任务。

提到C API,也稍微介绍一下,我们知道windows操作系统的api也好,Linux的系统api也好,或者是想给Ruby、Python编写扩展模块,C 语言形式的函数定义都是唯一的选择。C语言就好像是一个中间层或者是胶水,如果想把不同编程语言实现的功能模块混合使用,C语言是最佳的选择。

提了这么多关于C语言的好处,那么学习C语言是否适合就看你自己的判断了,例如要进行一个嵌入式项目,或者需要进行服务器端开发,或者写一个性能相 关的组件等等,C语言都是比较好用的选择。另外也可以在C++的使用过程中有意的使用C语言的思考方式,汲取C语言简洁明快清晰地设计思路,对编程设计水 平会有很大的提高。

C语言学习方法

在前面http://sunxiunan.com/?p=1597 曾经提到过一个比较系统学习一门新的编程语言的方式,C语言学习也可以按照类似的顺序:阅读参考书,阅读代码,编写调试实际程序,上网参与讨论,研究高级话题。

学习语言的开始一般是阅读参考书。我建议选择几本非常经典的好书,仔细完整反复阅读几遍,“书读百遍其义自现”。选择C语言学习的好处是,这几本书基本上完整涵盖了C语言编程领域的方方面面,不会像C++那样,即使读完一堆书还是有些糊涂,依然有这样那样难懂的陷阱。

1,参考书籍

在豆瓣上列了一个书单,大家可以直接参考http://book.douban.com/doulist/636329/

在下面简单点评一下,阅读顺序最好参照列出的顺序。

《The C Programming Language》http://book.douban.com/subject/1230004/

image

如果你只想买一本书学习C语言,只需要买这一本就够了。如果你经费足够,建议你多买几本,办公室、家里都放上一本,随手都可以翻翻。用三个词语来形 容它就是:经典!经典!经典!这本薄薄的只有二百多页的小书涵盖了C语言的方方面面,前无古人而且后无来者,任何溢美之词都不足以形容它。

《The C Programming Language》(后面称为 K&R)里面包含了一个简单的语法解析器,包含了malloc如何实现,包含了一个完整的操作系统目录浏览程序,这些程序的实用性极高,可以这样 说,如果学习任何一门语言能够自己独立动手实现以上的功能,基本上就可以算是入门了。K&R书里面每段都蕴含着非常值得探究的软件开发工程实践经 验,如果没有一定的开发经验,其实是看不出来这些冰山下面的内容的,比如开头一章就提出用写完整代码这种方式来教学,而在书中那些C语言的陷阱或者可能出 问题的地方,都有提到,但是由于篇幅所限,写的非常简约,很难让人一下就看懂。我正在完整的逐字逐句的阅读此书,希望能稍作注解,写几篇博客分享一下。

《C程序设计语言(第2版·新版)》http://book.douban.com/subject/1139336/

这是K&R的中文译本,可以先从中文译本看起,然后再读一遍英文原版,既可以学习英文,又可以体会原文那种简约优美的风格。

《C陷阱与缺陷》http://book.douban.com/subject/2778632/

《C专家编程》http://book.douban.com/subject/2377310/

这两本书也是学习及使用C语言的朋友必备的两本书,比如《C专家编程》,专门用两三个章节详细介绍C语言中数组与指针的不同之处,这两本书在某种程度上算是对K&R略过的地方做了详细补充,强烈推荐。

《C语言参考手册》http://book.douban.com/subject/2132084/

这是最后一本强烈推荐你最好买回家作为案头书必备的参考书。前面几本书或者稍显简略,或者专注某个特定专题,都不适合遇到问题时翻查。这本《C语言参考手册》可以看作是C语言编程的《新华字典》,全面而权威。里面还涵盖了C99的内容,紧跟时代潮流。

下面几本书都可以作为交叉参考,也都很有价值,也是建议大家都买下来,好书如朋友,日久弥新,像是我推荐的这几本书在douban或者amazon上评分都非常高,而且反复再版。

《C和指针》http://book.douban.com/subject/1229973/

指针的重要性如何,学过C语言(或者C++)的朋友都知道,这本书更是把指针拔高到了与C语言平起平坐的地位,其实也是从头开始介绍,作为教学参考书也是可以的。

《C标准库》http://book.douban.com/subject/3775842/

这本书是专门介绍C语言的标准库如何实现的,比如malloc算法,用标准的C语言该如何写?strlen这个函数应该如何实现?尽管书中不少代码与真实的C标准库相差很多(由于标准库需要考虑性能优化,很多函数有一些特定的trick),但是绝对值得参考。

《你必须知道的495个C语言问题》 http://book.douban.com/subject/3422332/

这本书其实就是C-FAQ的印刷版本,C-FAQ在各种编程语言的FAQ中可以称得上质量一流。如果你想应聘或者招聘C语言相关程序员,这本书一定要参考。

《Linux C编程一站式学习》http://book.douban.com/subject/4141733/

这本书是基于特定操作系统Linux来介绍C语言编程,可作为计算机相关专业的教科书或入门参考书,也是书单里面唯一一本国人原创的编程书籍,非常难得。书中几乎所有内容都在网上直接公开,针对读者的意见进行修改,这也是非常难得的一种开放态度。非常推荐大家买一本。

学习C语言,一定不能只读书,应该动手练习完成书里面的项目需求(比如编写一个目录浏览器)以及每章的练习题目。这就需要有可以实验的环境,下面针对不同操作系统简单做一下介绍。

2,动手实验环境搭建

也没有调查过,不知道现在学校里学习C语言是不是依然跟着谭浩强老师用TurboC2.0编程,如果还是这个组合的话,那就太差劲了,赶快抛开它们。

下面主要介绍不同操作系统平台下的集成编程环境,基于初学者以及我个人喜好,就不推荐大家命令行下用vim编程了,直接上IDE。

Windows系统下推荐大家使用Code::blocks这个软件。这个软件最大优点是自带了基于mingw的GCC以及GDB,只要下载70M 左右软件包,就可以完整支持C++、C语言编程了。各种功能(比如调试功能)也很强大,版本更新也比较快。注意下载选择名字有mingw的文件,比如最新 版本是codeblocks-10.05mingw-setup.exe(版本也许有所不同)。

主页:http://www.codeblocks.org/

image

如果需要做Windows操作系统的开发,可以下载Visual C++ 2010 Express。

image

因为Code::Blocks不包含Windows编程头文件(实际是因为没有Windows SDK),无法编写Windows操作系统相关的界面应用程序或者服务类程序。而VC++Express自带了这些头文件以及编程库,虽然功能稍微简陋, 但对于练习使用基本够用。

主页:http://www.microsoft.com/express/windows/

对于计算机专业的学生朋友,建议大家使用Linux操作系统,或者更详细一点是使用Xubuntu操作系统作为桌面,使用Netbeans和GCC 这个组合(当然也可以选择Code::Blocks)。在Xubuntu下可以通过apt-get install build-essential这个命令安装gcc相关程序,已经可以在Terminal下编译C语言程序了,但为了使用方便,大家可以选择 Netbeans的C++支持包,在Netbeans网站上就能下载。

image

主页:http://netbeans.org/features/cpp/index.html

如果使用苹果Mac系统,毫无疑问XCode就是编程的绝佳选择,XCode可以在苹果开发者网站上免费下载,在IPhone SDK中也包含了XCode。

image

主页:http://developer.apple.com/technologies/tools/xcode.html

如果手头没有合适的编程环境,还需要实验一些简单的代码,可以用http://codepad.org/ 提供的服务,在线编写运行代码。

image

另外建议大家申请一个github.com的账号,在gist.github.com可以保存自己的练习代码,就不需要随身带着U盘了。

3,网络资源

如果想用十分钟时间了解一下C语言的来龙去脉、前世今生,维基百科这个页面http://en.wikipedia.org/wiki/C_%28programming_language%29 是最佳选择。

从维基百科可以看到,C语言1972年由Dennis Ritchie设计的命令式、结构化范式编程语言。类型为静态的弱类型,需要显式定义。最新国际标准为C99。设计上主要受到了B、ALGOL68、汇编 语言、PL/I、FORTRAN的影响,C语言也影响了大量编程语言,如C++、Objective-C、C#、Java、Go、PHP、Python等 等(个人觉得受C影响很大的是PHP,基本上有C编程基础的程序员,很容易就能上手PHP了,除了PHP的OO部分)。

在维基百科条目中有很大篇幅介绍了作者认为C语言缺失的特性,比如面向对象、多线程、GC、异常处理等等,当然这有些吹毛求疵,如果需要这些特性, 完全可以用其它程序语言。另外一个介绍的重点是“未定义行为”,有些我们认为理所当然的结果,其实在C语言标准中并没有明确定义,假定这些行为应该如何, 当程序使用另外的编译器或者不同版本编译器编译运行,都可能有bug产生。

接下来维基百科条目谈到了C语言的用处,必须承认尽管现在编程语言成百上千,能称之为“系统级”的少之又少,新兴语言中只有Go还能称得上。现在大 规模软件项目中完全选用C语言可能性不大,但是核心部分完全可以用C搭建,相对C++开发工具的高昂价格,C语言相关的免费辅助开发软件非常丰富,比如 splint,valgrind,不少核心库经过长期使用也都非常稳定。

由于C语言广泛支持各种平台以及编译器相对成熟可靠,不少编程语言选择C语言作为一个中间层,比如Glasgow Haskell编译器就是这样做的。

另一个可以找到大量C语言编程相关资料的地方是“美味书签”,通过搜索特定关键字 (C + programming)就可以找到很多值得挖掘的资源http://delicious.com/search?p=c+programming

还可以参考dmoz.org的C语言分类http://www.dmoz.org/Computers/Programming/Languages/C/ 相比美味书签时效性能差点,但是分类比较系统,查找也要容易一些。

程序员往往是懒惰的,“拿来主义”、“拷贝主义”很流行也很有效,当对某个函数或者关键字不是很理解的时候,看看别人是怎么使用的,会非常有启发性。这里介绍几个常用的代码搜索网站,最常用的是google的codesearch:http://codesearch.google.com ,可以通过不同条件及正则表达式搜索特定关键词。另外可以参考维基百科上一个“带有C语言示例的文章”分类,里面代码写的也很不错。还可以在github.com上搜索相关项目。在前面博客文章我还介绍了一个名为罗塞塔代码的网站http://rosettacode.org/ 这个网站上可以找到不同程序语言针对某个问题的解决方案,用于学习比较非常便利。

学习编程也需要大量阅读名家经典代码,与学中文英文需要大量阅读名著一个道理,C语言编程优质项目那是“彩旗飘舞,人山人海”,个人建议可以看看 Lua、Sqlite、Nginx这些项目的代码,代码量不多,而且代码质量也都比较高。另外可以看看Linux内核代码,坊间有不少书籍可以帮助解读。 关于如何很好的阅读代码,大家可以参考《Code Reading》这本书。

书看了几本,代码写了一些,也略微读了读其他人的代码,就应该用C语言来完成真实工作中碰到的问题,让C语言真正成为你的瑞士军刀。只有当你经常使用C语言来进行编程工作,经常思考如何通过C设计一个优雅高效的系统,才能更深刻的理解C语言设计哲学。

还可以到http://stackoverflow.com 参与回答问题,浏览其他人的问题解答来汲取知识,比如这篇http://stackoverflow.com/questions/2054939/char-is-signed-or-unsigned-by-default 就介绍了一个C语言关于char类型的小陷阱。

C语言学习当中,有一些难点需要多加注意,如pointer与array的不同之处,复杂类型定义如何解读,如何正确使用预处理preprocessor以及宏定义。其实这些内容在前面书籍都是反复提到,如果按部就班学习下来,应该不成问题。

当C语言学习的差不多时候,还可以学习一门动态语言,比如Lua或者Python,试着在实际工作项目中混合使用动态语言与C语言,一加一发挥出来的力量不仅仅是二,而是非常二(说笑一下,哈哈)。

还有什么问题,欢迎留言。

附录

一些有用的C语言网络资源:

C语言标准化组织ISO JTC1/SC22/WG14的主页,在这里可以找到ISO C的文档:http://www.open-std.org/jtc1/sc22/wg14/

《The Development of the C Language》作者Dennis Ritchie,极为经典的论文。 http://cm.bell-labs.com/cm/cs/who/dmr/chist.html

“C语言全景”这个网站内容很全面:http://www.softpanorama.org/Lang/c.shtml

Dan Saks在embedded.com上的专栏Programming Pointer ,里面文章很有深度,值得一读。

http://www.lysator.liu.se/c/c-www.html 这也是一个C语言资源汇总页面。

http://www.ioccc.org/index.html 混乱C语言代码大赛,很著名。

http://en.wikipedia.org/wiki/Underhanded_C_Contest 另外一个C语言编程大赛,主要面向黑客。

comp.lang.c以及c.moderated这两个讨论组推荐订阅,相当于互联网最大的C相关编程问题论坛:

http://groups.google.com/group/comp.lang.c

http://groups.google.com/group/comp.lang.c.moderated

这里对C语言的各种bit操作做了收集整理,不少题目在面试时候经常出现。http://graphics.stanford.edu/~seander/bithacks.html

台湾的惯C达人Jserv博客,建议大家订阅:http://blog.linux.org.tw/~jserv/

一些值得关注及研究的C语言相关项目:

TinyCC,被很多项目用作动态编译C语言的编译器引擎:http://bellard.org/tcc/

GCC的标准库实现:http://en.wikipedia.org/wiki/GNU_C_Library

Glib是GTK的底层辅助编程库,与C标准库是不一样的,在C语言上实现了面向对象机制:http://en.wikipedia.org/wiki/GLib

dietlibc在前面博客文章介绍过,C标准库的另一种实现:http://www.fefe.de/dietlibc/

一些C语言编程时可以使用的工具软件,帮你提高代码质量:

http://www.splint.org/

http://valgrind.org/

http://www.dwheeler.com/flawfinder/

PMD可用于检测重复代码 http://pmd.sourceforge.net/cpd.html

llvm的静态分析项目 http://clang-analyzer.llvm.org/

C语言编程规范编程标准:

http://en.wikipedia.org/wiki/MISRA_C

http://www.eecs.harvard.edu/~ellard/CS50-96/programming-style.html

http://developers.sun.com/solaris/articles/secure.html

cert这个文档国内有中文翻译版本:https://www.securecoding.cert.org/confluence/display/seccode/CERT+C+Secure+Coding+Standard

http://www.cs.utah.edu/dept/old/texinfo/standards/standards_toc.html

C语言编程电子书及教程:

http://publications.gbdirect.co.uk/c_book/ 这一本写的非常详细,你可以把它看成是类似谭浩强版的教科书。

http://www.knosof.co.uk/cbook/cbook.html 这一本云风曾经推荐过,相当深入的介绍了C99标准,深入细节时候需要读读。

http://www.duckware.com/bugfreec/index.html 这本书在网上流传一个中文版本,《编写优化、高效、无错地代码》,另外也有英文影印版《编程精粹》。

http://wangcong.org/blog/?page_id=196 作者王聪,也是相当hard geek,从两个样章看,包含了相当多的内容。

《C语言深度解剖》这本可以在百度文库或google搜到,可以读读,有些参考性。

《C标准和实现》作者姚新颜,他的《深度探索C、C++》算是当年比较有深度的书籍,可惜已经绝版了。这本书也可以在百度文库搜到。这本书也比较值得读。

良葛格C语言学习笔记 http://caterpillar.onlyfun.net/Gossip/CGossip/CGossip.html

C与C++的兼容性问题 http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B

另一个文档关于C与C++标准兼容性问题:http://david.tribble.com/text/cdiffs.htm

C Elements of Stylehttp://www.oualline.com/books.free/style/index.html

《Linux安全编程》http://www.dwheeler.com/secure-programs/

《C Craft》电子版 http://crypto.stanford.edu/~blynn/c/

《The function pointer tutorials》函数指针教程。http://www.newty.de/fpt/index.html

C语言编程及Unix系统调用,想用C在Unix或者Linux编程的朋友可以参考。http://www.cs.cf.ac.uk/Dave/C/

优化C、C++代码 http://www.eventhelix.com/RealtimeMantra/Basics/OptimizingCAndCPPCode.htm

图文并茂介绍C语言的指针 http://boredzo.org/pointers/

另外一篇介绍C语言优化的文章 http://www.prism.uvsq.fr/~cedb/local_copies/lee.html

一个C语言教学ppt http://www.slideshare.net/petdance/just-enough-c-for-open-source-programmers

一些Unix下C语言编程相关的文章 http://users.actcom.co.il/~choo/lupg/tutorials/index.html

Unix下如何建立静态、动态C语言函数库 http://users.actcom.co.il/~choo/lupg/tutorials/libraries/unix-c-libraries.html

如何使用GDB http://users.actcom.co.il/~choo/lupg/tutorials/debugging/debugging-with-gdb.html

一些C语言编程技巧 http://users.bestweb.net/~ctips/

Advanced C programming,高级C语言编程,可以提高水平,非常有帮助 http://www.mpi-inf.mpg.de/departments/rg1/teaching/advancedc-ws08/literature.html

C语言问答,这些题目也可用于面试 http://www.gowrikumar.com/c/

cygwin中文配置

cygwin 1.7版本中文配置方法:
添加LANG=zh_CN环境变量,可在系统属性添加,也可以直接添加到cygwin的启动脚本里面,脚本修改后为:


    @echo off
    set CYGWIN=tty notitle glob
    set LANG=zh_CN
    C:
    chdir C:\cygwin\bin

    bash –login –i

主要添加了两个环境变量。

这样就可以了,不用修改什么ls,less,甚至是inputrc都不用,直接就完美支持中文。

可参考:http://cygwin.com/cygwin-ug-net/setup-locale.html
Cygwin 1.7版 中文问题的解决(99%)

git子命令自动完成
cygwin安装完成后,默认是没有设置好git的completion的。设置方法在/etc/bash-completion.d/git
里面,也就是git的completion脚本。
(1)拷贝/etc/bash-completion.d/git文件到某个地方,如:~/.git-completion.sh
(2)添加以下内容到.bashrc或者.bash_profile,具体位置具体修改


    source ~/.git-completion.sh

重启cygwin即可。

Cygwin中git log无显示内容

在Cygwin中使用git,设置过git config core.pager more后,在运行git log时不显示内容,不知道别人有没有出现过这个问题,反正我是出现过,原因是没事瞎折腾。
Cygwin中默认是没有more的,可以用git config core.pager less代替上面的命令。

Personal CSS Hacks for IE6, IE7, IE8

Are CSS hacks an evil? Yes, of course.

But we will use them, while browsers like IE6, IE7 and IE8 will exist and while Microsoft will not create a normal browser, which will stand on equal with modern browsers like FireFox, Safari, Chrome and Opera.

We, web developers, are constantly faced with deficiencies of Internet Explorer, and CSS hacks allow to overcome them in most cases.

In this post I would like to group the personal CSS hacks for each of the 3 popular versions of IE. Most likely you already know the CSS hacks for IE6 and IE7, but for IE8 probably not. Therefore the focus of this article is on a personal CSS hack for Internet Explorer 8.
CSS hack for Internet Explorer 6

It is called the Star HTML Hack and looks as follows:


* html .color {color: #C39;}

This hack uses fully valid CSS.
CSS hack for Internet Explorer 7

It is called the Star Plus Hack.


*:first-child+html .color {color: #66F;}

Or a shorter version:


*+html .color {color: #66F;}

Like the star HTML hack, this uses valid CSS.
CSS hack for Internet Explorer 8

I learned about it from a familiar russian web developer, who’s found it by experimental way. It looks like this:


.color {color: #0FC\0/;}

There are several similar variants of this hack, but this is the easiest. It’s very easy to remember. Just add the \0/ at the end of a CSS rule. This hack must go after the rules for all another browser, i.e.:


.color {color: #777;} /* for all browsers */
* html .color {color: #C39;} /* for IE6 */
*+html .color {color: #66F;} /* for IE7 */
.color {color: #0FC\0/;} /* for IE8, going last */

This hacks does not use valid CSS, therefore I recommend to use a conditional comments.
Demo

I’ve created a simple demo, it displays, what personal CSS hacks works fine for all 3 versions of IE. Take a look.

如何在svn系统中使用git

如果正在使用svn,打算换到git,又暂时不想放弃已有的svn代码库,可以选择git- svn。说一说我自己从svn到git的经验吧。

开始

安装最新版本的git,从git 1.5.3以后支持git-svn,git和svn的配合就要借助这个功能。

安装完毕后要做一些简单的配置。最直接的做法就是创建修改~/.gitconfig。下面是我的.gitconfig


[user]
        name = Robin Lu
        email = ---@gmail.com
[color]
        diff = auto
        status = auto
        branch = auto
[alias]
  st = status
  rb = svn rebase
  ci = commit -a
  co = checkout

[user]部分标示出使用者的身份,你提交的代码会自动引用这一身份信息。[color]设置命令输出的颜色。[alias]部分可以简化一些常用命令,比如在这里将git status简化为git st。
初始化代码库

首先用git-svn来初始化本地的代码库(repository)


git svn clone -s svn-repository-url

svn-repository-url部分使用svn代码库的url。如果要从trunk目录或者某个branch目录里check out,要把-s换成-T、-b等选项。具体参看man git-svn。这个命令时间比较长,因为需要同步所有的提交历史,还好只此一次,以后不会这么慢了。做完这一步,在本地就有了一个完整的代码库,包括所有commit的历史和log,已经可以开始用它来进行开发工作了。

不过,在开始开发之前,最好先做一次垃圾搜集:


git gc

它对代码库的信息进行垃圾搜集和压缩,最明显的作用就是减小磁盘占用空间。第一次做效果尤其明显。

你可以检查一下代码库的状态:


git status

现在应该在一个叫”master”的分支(branch)上。

用这个命令来显示出所有的分支(branch):


git branch -a

master前有一个*号,代表你现在所处的分支,另外还有一个分支叫trunk,它是一个远程分支(remote branch),对应的是远程svn代码库。master实际上是trunk的一个本地分支。

接下来,需要配置忽略文件,让git忽略一些目录中不希望加入代码库的文件,类似svn propset svn:ignore。全局有效的忽略文件列表可以添加在./.git/info/exclude文件中。比如我需要忽略所有vi产生的swp文件:

.*.swp

对于和目录有关的忽略文件设置可以在该目录下创建.gitignore,然后加入需要忽略的内容,比如我希望忽略根目录下的log,tmp等目录,可以直接在根目录下的.gitignore中加入:

log
tmp

开发流程

可以开始工作了。用git后开始养成一个新习惯,就是工作前先创建新分支:


git checkout -b new_branch

-b后是分支名,创建的同时,你要转到了新分支上。尽量保持master上没有未提交到svn的commit,这样随时都可以很容易的产生一个干净的分支。

接下来你可以写代码,修改文件或者添加文件。如果想看看修改了什么,可以用:


git diff

如果对某个修改不满意,希望恢复原状,可以使用:


git checkout path/filename

相当于svn revert

git引入一个索引(index)的概念,提交前,需要把要提交的文件加入到git索引(index)中:


git add path/filename1
git add path/filename2
...

然后提交


git commit -m "提交感言"

每次commit都是提交索引(index)中的内容。

如果要一次提交所有修改过的文件,可以一次性添加,然后提交


git add .
git commit -m "提交感言"

如果只是修改,并没有添加新文件,可以直接用下面的命令:


git commit -a -m "提交感言"

将被修改文件加入索引并提交,一次完成全过程。

在修改加入所索引后,如果想看看索引内容中都所了什么修改,可以用:


git diff --cached

适合在提交前做最后的code review。

查看最近一次提交的内容,可以使用


git show

修改中随时查看当前代码库的状态:


git status

相当于svn status

删除和移动某个文件:


git rm file
git mv file newfile

提交到svn

在完成了几轮工作后,要将本地内容提交到远程svn中,可以先让当前分支和远程svn同步:


git svn rebase

然后将所有已经合并到master分支的本地修改提交到svn


git svn dcommit

如果在git svn rebase时发生代码冲突,需要先手动解决冲突,然后用git add将修改加入索引,然后继续rebase


git svn rebase --continue

缺点

最后说说这种工作方式的缺点。这个话题稍微复杂一点。

svn和git的工作原理毕竟不同,git对代码提交的非线性特性在svn中难以再现,如果使用了git-merge或者git-pull,再提交到svn,相关分支上的提交历史有可能无法体现在svn上。从svn的使用者的角度,无法辨别这是一个提交还是一次合并,所以在和svn协作过程中,尽量不要使用merge,或者说,尽量让代码库保持线性。

我的经验是,如果不在乎svn中是否反映出提交历史,使用merge也无妨。比如完成工作后,可以将工作分支合并到主分支中去:


git checkout master
git merge new_branch

先用checkout命令切换回master分支,然后将新分支中内容合并进来。然后在master分支上做git svn rebase和dcommit。从svn来看,这就是一个commit,new_branch上的提交历史在svn上体现不出来。(有例外情况,以后再讨论)。

还有一个解决办法是尽量保持git代码库的线性特征。比如在new_branch分支中,先和master做rebase,再合并到master分支中:


git rebase master
git checkout master
git merge new_branch

然后在master上做dcommit,就可以在svn代码库中看到完整的提交历史。

如果看到这已经有点头晕了,可以干脆不管它,就按照前面的做法,直接在你的工作分支里dcommit,等对非线性开发有一定了解再来看各种情况。

好了,基本上知道这些就可以干活了。

screen命令在freebsd安装和使用

Screen工具是一个终端多路转接器,在本质上,这意味着你能够使用一个单一的终端窗口运行多终端的应用。

安装
# cd /usr/ports/sysutils/screen
# make install clean

使用
# screen
//以下^A表示同按“Ctrl + A”键
# ^A c //Create,开出新的 window
# ^A n //Next,切换到下个 window
# ^A p //Previous,前一个 window
# ^A ^A //在两个 window 间切换
# ^A w //Windows,列出已开启的 windows 有那些
# ^A 0…9 //切换到第 0..9 个 window
# ^A t //Time,显示目前的时间,与系统的 load
# ^A K //kill window,强制关掉目前的 window
# ^A ? //Help,显示简单说明
# ^A d //detach,将目前的 screen session (可能含有多个 windows) 丢到背景执行
当 按了 ^A d 把 screen session detach 掉后,会回到还没进 screen 时的状态,此时在 screen session ?每个 window 内跑的 process (无论是前景/背景)都在继续执行,即使 logout 也不影响,这个就是我喜欢的,能掉到后台去,O(∩_∩)O哈哈~

# screen -ls //显示所有的 screen sessions
# screen -r [keyword] //选择一个 screen session 回来 (捡回来) , 恢复离线的screen作业, 单独输入 screen -r 也行的.

补充说明:
screen是一个多重视窗管理程序,此处所谓的视窗,是指一个全屏幕的文字模式画面。通常只有在使用telnet登入主机或是使用老式的终端机时,才有可能用到screen程序.

在linux应用screen命令应该差不多吧!
me在连接到dreamhost.com的空间那里时,尝试输入screen , 居然存在这命令啊,爽,以后在dreamhost又多一样玩意了,看来dreamhost的主机不错.

非常非常爽的一个工具,看了书之后研究了一下,非常爽

# screen
//以下^A表示同按“Ctrl + A”键
# ^A c //Create,开出新的 window
# ^A n //Next,切换到下个 window
# ^A p //Previous,前一个 window
# ^A ^A //在两个 window 间切换
# ^A w //Windows,列出已开启的 windows 有那些
# ^A 0…9 //切换到第 0..9 个 window
# ^A t //Time,显示目前的时间,与系统的 load
# ^A K //kill window,强制关掉目前的 window
# ^A ? //Help,显示简单说明
# ^A d //detach,将目前的 screen session (可能含有多个 windows) 丢到背景执行
当 按了 ^A d 把 screen session detach 掉后,会回到还没进 screen 时的状态,此时在 screen session ?每个 window 内跑的 process (无论是前景/背景)都在继续执行,即使 logout 也不影响。
# screen -ls //显示所有的 screen sessions
# screen -r [keyword] //挑个 screen session 回来 (捡回来)

【转】一些被忽视的 PHP 函数

真的是不用不知道,其实我们熟悉的 PHP 还有很多好东西没有发掘。看到这篇文章,当时就泪奔了好几回,重点推荐下,顺便我自己也做个整理。
sys_getloadavg()

这个函数返回当前系统的负载均值信息(当然 Windows 下不适用),详细文档可以翻阅 PHP 的相关文档。文档中有段示例代码,基本上也就能看出它的用途了。


< ?php
$load = sys_getloadavg();
if ($load[0] > 80) {
    header('HTTP/1.1 503 Too busy, try again later');
    die('Server too busy. Please try again later.');
}
?>

PS,如果“很不幸”得你的 PHP 环境中没有这个函数,可以考虑使用下面这段代码 via


if (!function_exists('sys_getloadavg')) {
    function sys_getloadavg()
    {
        $loadavg_file = '/proc/loadavg';
        if (file_exists($loadavg_file)) {
            return explode(chr(32),file_get_contents($loadavg_file));
        }
        return array(0,0,0);
    }
}

这一特性如果使用得当,能减轻服务器部分压力。
pack()

pack 对应的还有个函数为 unpack,用于压缩二进制串,文中的作者的示例非常清楚


$pass_hash = pack("H*", md5("my-password"));

如果你使用 PHP5,那么可以直接这样子


$pass_hash = md5("my-password", true); // PHP 5+

这样做的好处之一是能减少串存储空间(能节省多少呢?可能又会是另篇文章了)。

这里还有个示例代码可以 pack 数组 via


< ?php
function pack_array($v,$a) {
 return call_user_func_array(pack,array_merge(array($v),(array)$a));
}
?>

cal_days_in_month()

该函数可以直接返回指定月份中的天数,例如


$days = cal_days_in_month(CAL_GREGORIAN, date("m"), date("Y")); // 31

我敢保证,你自己实现过类似功能的函数 :^)
_()

呃,这的确也是个 PHP 函数(也有可能是最短的 PHP 内置函数)。_() 是它的“小名”,它的大名是 gettext()。

写过 WordPress 皮肤的朋友会了解 __() 以及 _e() 这些函数,其实 PHP 早已经自带了相关的功能。


// Set language to German
setlocale(LC_ALL, 'de_DE');

// Specify location of translation tables
bindtextdomain("myPHPApp", "./locale");

// Choose domain
textdomain("myPHPApp");

echo _("Have a nice day");

利用 gettext 可以编写多语言的应用,现在您感兴趣的可能就是如何编写 locale 文件,这但已经不是此文涉及的重点,更多信息可以移步到这里。
get_browser()

坦白讲,见到这个函数我当时就彻底泪奔。有了这个函数,再也不用自己去分析 $_SERVER['HTTP_USER_AGENT'] 这个字符串了。

更多的信息可以参考这里。在使用此函数前,你可能需要个 browscap.ini 配置文件,相信你可以搞定的。
debug_print_backtrace()

以前查看函数调用堆栈,我会使用 xdebug 等的扩展,其实 PHP5 版本以后已经内置了相关的函数。

顺便再分享个“蛋疼”的小技巧,如果你记不住这个函数的名字,可以用这段代码同样能达到目的(看起来还是记住那个函数靠谱):


< ?php
$e = new Exception();
print_r(str_replace('/path/to/code/', '', $e->getTraceAsString()));

natsort()

这个函数用于自然排序,这个大家可能都要用到。贴下相关的文档链接以及示例代码


$items = array("100 apples", "5 apples", "110 apples", "55 apples");

// normal sorting:
sort($items);
print_r($items);
    # Outputs:
    # Array
    # (
    #     [0] => 100 apples
    #     [1] => 110 apples
    #     [2] => 5 apples
    #     [3] => 55 apples
    # )

natsort($items);
print_r($items);
    # Outputs:
    # Array
    # (
    #     [2] => 5 apples
    #     [3] => 55 apples
    #     [0] => 100 apples
    #     [1] => 110 apples
    # )

有关自然排序的算法规则,可以参考这里的文档。
glob()

这个函数的功能同样让人感到泪奔,先不说功能直接上示例代码


foreach (glob("*.php") as $file) {
    echo "$file\n";
}

相比你已经了解该函数的用途了,那么我们就可以有更多的“玩法”,例如就显示目录(via):


$dirs = array_filter(glob($path.'*'), 'is_dir');

当然,文件递归你也可以考虑使用下 SPL 扩展。

补充 by 神仙:

glob 有个参数选项 GLOB_ONLYDIR 就可以只列目录

PHP Filter

如果你还在正则验证字符串,那么就真的“Out”了。自 PHP5.2 版本以后,内置了 PHP Fliter 模块用于专门验证 电子邮件、URL 等是否合法,示例代码:


var_dump(filter_var('bob@example.com', FILTER_VALIDATE_EMAIL));

由于是新生的模块,因此还有很多的陷阱,例如


filter_var('abc', FILTER_VALIDATE_BOOLEAN); // bool(false)
filter_var('0', FILTER_VALIDATE_BOOLEAN);   // bool(false)

但这不影响我们去尝试。有关 PHP Filter 的更多信息,相信能拎出来另外写篇文章了。

– Split –

最后,感叹 PHP 其实是个历久弥新的工具,不小心我们就会悲剧性得重复造了只轮子。因此,时常看看 PHP 文档每次都会有新的收获。
转自:http://www.gracecode.com/archives/3013/

document.createElement()的用法

document.createElement()是在对象中创建一个对象,要与appendChild() 或 insertBefore()方法联合使用。其中,appendChild() 方法在节点的子节点列表末添加新的子节点。insertBefore() 方法在节点的子节点列表任意位置插入新的节点。

下面,举例说明document.createElement()的用法。


<div id="board"></div>

例1:


        <script type="text/javascript">
            var board = document.getElementById("board");
            var e = document.createElement("input");
            e.type = "button";
            e.value = "这是测试加载的小例子";
            var object = board.appendChild(e);
        </script>

效果:在标签board中加载一个按钮,属性值为“这是测试加载的小例子”。
例2:


        <script type="text/javascript">
            var board = document.getElementById("board");
            var e2 = document.createElement("select");
            e2.options[0] = new Option("加载项1", "");
            e2.options[1] = new Option("加载项2", "");
            e2.size = "2";
            var object = board.appendChild(e2);
        </script>

效果:在标签board中加载一个下拉列表框,属性值为“加载项1”和“加载项2”。
例3:


        <script type="text/javascript">
            var board = document.getElementById("board");
            var e3 = document.createElement("input");
            e4.setAttribute("type", "text");
            e4.setAttribute("name", "q");
            e4.setAttribute("value", "使用setAttribute");
            e4.setAttribute("onclick", "javascript:alert('This is a test!');");
            var object = board.appendChild(e3);
        </script>

效果:在标签board中加载一个文本框,属性值为“使用setAttribute”。 当点击这个文本框时,会弹出对话框“This is a test!”。
根据上面例子,可以看出,可以通过加载对象的属性来设置,参数是相同的。使用e.type=”text” 和 e.setAttribute(“type”,”text”)效果是一致的。
下面,我们用实例来讲述一下appendChild() 方法和insertBefore() 方法的不同。
比如我们要在下面这个div中插入一个子节点P时:

<div id="test"><p id="x1">Node</p><p>Node</p></div>

我们可以这样写:


<script type="text/javascript">
  var oTest = document.getElementById("test");
  var newNode = document.createElement("p");
  newNode.innerHTML = "This is a test";
  //测试从这里开始
  //appendChild方法:
  oTest.appendChild(newNode);
  //insertBefore方法:
  oTest.insertBefore(newNode,null);
</script>

通过以上的代码,可以测试到一个新的节点被创建到了节点div下,且该节点是div最后一个节点。很明显,通过这个例子,可以知道appendChildhild和insertBefore都可以进行插入节点的操作。
   在上面的例子中有这样一句代码:oTest.insertBefore(newNode,null) ,这里insertBefore有2个参数可以设置,第一个是和appendChild相同的,第二却是它特有的。它不仅可以为null,还可以为:


<script type="text/javascript">
  var oTest = document.getElementById("test");
  var refChild = document.getElementById("x1");
  var newNode = document.createElement("p");
  newNode.innerHTML = "This is a test";
  oTest.insertBefore(newNode,refChild);
</script>

效果:这个例子将在x1节点前面插入一个新的节点
又或:


<script type="text/javascript">
  var oTest = document.getElementById("test");
  var refChild = document.getElementById("x1");
  var newNode = document.createElement("p");
  newNode.innerHTML = "This is a test";
  oTest.insertBefore(newNode,refChild.nextSibling);
</script>

效果:这个例子将在x1节点的下一个节点前面插入一个新的节点

还可为:


<script type="text/javascript">
  var oTest = document.getElementById("test");
  var newNode = document.createElement("p");
  newNode.innerHTML = "This is a test";
  oTest.insertBefore(newNode,oTest.childNodes[0]);
</script>

  这个例子将在第一子节点前面插入一个新的节点,也可以通过改变childNodes[0,1,...]来在其它位置插入新的节点

由于可见insertBefore()方法的特性是在已有的子节点前面插入新的节点,但例一中使用 insertBefore()方法也可以在子节点列表末插入新节点的。两种情况结合起来,发现insertBefore()方法插入节点,是可以在子节点列表的任意位置。
  从这几个例子中得出:

  appendChild() 方法在节点的子节点列表末添加新的子节点。
  insertBefore() 方法在节点的子节点列表任意位置插入新的节点。

IE与Firefox在Javascript上的区别的几小点

1、innerText和textContent
这两个属性功能相同,前者用于IE,后者用于Firefox
例:


if(document.all) {
document.getElementById('element').innerText = "text";
}else {
document.getElementById('element').textContent = "text";
}

2、获取键盘输入字符keyCode
在IE下可以直接使用event.keyCode,但是在Firefox下不能这样使用,在FF中会往onkeyup之类的事件中传入隐含的参数e,可以用which和charCode(Opera支持which和keyCode),可以这样:


element.onkeyup = function(e) {
var code = 0,e = e||event;
code = e.keyCode||e.which||e.charCode;
return code;
}

3、其它的一些Javascript
动态设置HTML控件属性


obj.setAttribute('name', 'val');

禁止INPUT输入框的自动完成功能


<input type="text" name="uname" id="uname" value="" autocomplete="off" />

也可以在脚本中动态设置


obj = document.getElementById('uname');
obj.setAttribute('autocomplete","off");

在脚本中直接给控件设置样式表,之前一直是用obj.style.color=”#000″类似的方法设置控件的CSS属性,一行代码一个属性,太麻烦了,这有一个cssText可以方便的设置HTML控件的样式


var obj = document.getElementsByTagName("DIV");
obj[0].cssText = "width:100%;height:50%;border:1px #000 solid;"
Page 1 of 151234567810...Last »