﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-xiaoguozi's Blog-随笔分类-Linux</title><link>http://www.cppblog.com/guojingjia2006/category/10141.html</link><description>Pay it forword - 我并不觉的自豪，我所尝试的事情都失败了······习惯原本生活的人不容易改变，就算现状很糟，他们也很难改变，在过程中，他们还是放弃了······他们一放弃，大家就都是输家······让爱传出去，很困难，也无法预料，人们需要更细心的观察别人，要随时注意才能保护别人，因为他们未必知道自己要什么·····</description><language>zh-cn</language><lastBuildDate>Wed, 04 Sep 2013 13:08:52 GMT</lastBuildDate><pubDate>Wed, 04 Sep 2013 13:08:52 GMT</pubDate><ttl>60</ttl><item><title>Nagios插件编写及调试方法</title><link>http://www.cppblog.com/guojingjia2006/archive/2013/09/03/202981.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Tue, 03 Sep 2013 01:39:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2013/09/03/202981.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/202981.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2013/09/03/202981.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/202981.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/202981.html</trackback:ping><description><![CDATA[<div><p style="text-indent: 2em">前言：  Nagios是相当不错的监控工具，被称作是&#8220;监控之神&#8221;，但同样也有&#8220;难搞死&#8221;头衔。发挥Nagios一切魅力的都是他的插件，正因为丰富多样的插件让 nagios有血有肉。监控的内容不断在变化，插件也不断变化，默认的一些插件可能越来越不能满足需求，这个时候就要自己来写些插件了。</p> <p style="text-indent: 2em">以下就是用我的第一个Nagios插件来说明编写方法和我遇到一些问题调试方法。如果你有耐心可以通篇看完，应该对第一次写的人来说会有很大帮助（如果你看不懂，可能是我写得不清楚 那就没办法了 表达能力有限）</p> <p style="text-indent: 2em">需求：</p> <p style="text-indent: 2em">监控普通磁盘的健康状况（普通磁盘以外还有RAID、阵列的监控是不同方法来做的，这里先不讨论，先从最简单的入手），定期进行检测，并进行报警，报警内容磁盘是否正常，不正常是什么状态。</p> <p style="text-indent: 2em">分析编写过程：</p> <p style="text-indent: 2em">我写脚本的前提都是先从手动成功完成，再到自动化（我想其它人的思路应该都一样的）</p> <p style="text-indent: 2em">1、找到监控磁盘的方法</p> <p style="text-indent: 2em">通过一番查找 smartctl 这个命令是比较不错的&nbsp; centos slackware一般的默认都有这个</p> <p style="text-indent: 2em">smartctl -H /dev/sda&nbsp; 只检测状态</p> <p style="text-indent: 2em">smartctl -i /dev/sda&nbsp;&nbsp; 只检测硬盘信息</p> <p style="text-indent: 2em">smartctl -a /dev/sda 检测所有信息</p> <p style="text-indent: 2em">2、获取检测信息</p> <p style="text-indent: 2em"># smartctl -H /dev/sda</p> <p style="text-indent: 2em">smartctl version 5.38 [x86_64-redhat-linux-gnu] Copyright (C) 2002-8 Bruce Allen</p> <p style="text-indent: 2em">Home page is http://smartmontools.sourceforge.net/</p> <p style="text-indent: 2em">SMART Health Status: OK</p> <p style="text-indent: 2em">关键的最后一行说明磁盘的情况 &nbsp; &nbsp; &nbsp; 截取&nbsp; DISK_HEALTH=`smartctl -H /dev/sda | tail -1 | cut -d: -f2-&nbsp; `</p> <p style="text-indent: 2em">3、 进行关键判断</p> <p style="text-indent: 2em">据我所知道的 smartctl 5.38&nbsp; 是出以上的結果 为OK</p> <p style="text-indent: 2em">而 smartctl 5.39 是出以下結果</p> <p style="text-indent: 2em">=== START OF READ SMART DATA SECTION ===</p> <p style="text-indent: 2em">SMART overall-health self-assessment test result: PASSED</p> <p style="text-indent: 2em">关键词是PASSED</p> <p style="text-indent: 2em">所以要分析判断多种情况</p> <p style="text-indent: 2em">4、脚本编写步骤</p> <p style="text-indent: 2em">1）了解nagios插件编写规范</p> <p style="text-indent: 2em">Nagios的插件可以用脚本（shell、Perl）C编译后的可执行程序，但必须满足以下两件事：</p> <p style="text-indent: 2em">A、既出时有一个返回值</p> <p style="text-indent: 2em">B、至少向标准输出设备（STDOUT）输出一行文件。（但也不能太大，默认是4K，如果想大些，修改源程序吧，方法搜。) </p> <p style="text-indent: 2em">返回值定义：</p> <p style="text-indent: 2em">Plugin Return Code Service State DISK State <br />0 OK OK 或者PASSED <br />1 WARNING 插件警告&nbsp; DISK报警只分OK或者CRITICAL <br />2 CRITICAL&nbsp; DISK检测非OK 或者PASSED <br />3 UNKNOWN&nbsp; 未知状态 </p> <p style="text-indent: 2em">2)插件编写SHELL速成法</p> <p style="text-indent: 2em">在这里我选用我最熟悉的SHELL进行脚本编写 ,</p> <p style="text-indent: 2em">我的速成法就是，直接去nagios exchange 去下比较成熟的比较简单的shell脚本，这样会从一开始借鉴别人好的方法，养成好的习惯，而且只要你有一点SHELL编程经验也可以很快写得像一个老手。（不过不要把自己搞晕了就行）</p> <p style="text-indent: 2em">3）以下是我的check_disk_health.sh</p> <p style="text-indent: 2em">#!/bin/bash<br /># ========================================================================================<br /># disk health&nbsp; plugin for Nagios<br />#<br /># Written by&nbsp;&nbsp;&nbsp; : Ajian<br /># Release&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 1.2.0<br /># Creation date : 2009-07-28<br /># Revision date : 2009-07-30<br /># Description&nbsp;&nbsp; : Nagios plugin (script) to check disk health .<br />#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This script has been designed and written on Linux System.<br />#<br /># USAGE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : ./check_disk_health.sh [-d (disk)]<br />#<br /># Exemple: ./check_cpu_stats.sh<br />#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ./check_cpu_stats.sh -d /dev/sda<br />#<br />#<br /># HISTORY :<br />#&nbsp;&nbsp;&nbsp;&nbsp; Release&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp; Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; Authors&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Description<br /># --------------+---------------+----------------------+-----------------------------------<br />#&nbsp; 1.0.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | 2009-07-28&nbsp;&nbsp;&nbsp;&nbsp; | Ajian&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Create the script<br />#&nbsp; 1.2.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | 2009-07-30&nbsp;&nbsp;&nbsp; |&nbsp; Ajian&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | modify the script and run well ,fix a bug.<br /># -----------------------------------------------------------------------------------------<br /># NOTICE:<br />#-----------------------------------------------------------------------------------------<br />#&nbsp;&nbsp;&nbsp;&nbsp; You should have the root Permissions ,You can use sudo to realize .<br /># -----------------------------------------------------------------------------------------&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;<br /># Nagios return codes<br />#定义 nagios返回的状态变量<br />STATE_OK=0<br />STATE_WARNING=1<br />STATE_CRITICAL=2<br />STATE_UNKNOWN=3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;<br /># Paths to commands used in this script.&nbsp; These may have to be modified to match your system setup.<br /># 定义关键的核心命令smartctl 路径 如果你的系统不是这个地址，请更改。 以下注释的是调试的信息，是自动获取命令路径的方法。<br />SMARTCTL="/usr/sbin/smartctl"<br />#SMARTCTL=`which smartctl`<br />#if [ $? -ne 0 ]; then<br />#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo " smartctl is found in $SMARTCTL ; Go on ... "<br />#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "smartctl the command cannot find"<br />#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit $STATE_UNKNOWN<br />#fi<br /># Plugin parameters value if not define<br /># 定义默认的检测硬盘<br />CHECK_DISK="/dev/sda"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;<br /># Plugin variable description<br /># 插件描述信息<br />PROGNAME=$(basename $0)<br />RELEASE="Revision 1.2.0"<br />AUTHOR="(c) 2009 Ajian ()"<br />&nbsp;<br /># Functions plugin usage<br /># 插件的使用方法函数<br />print_release() {<br />&nbsp;&nbsp;&nbsp; echo "$RELEASE $AUTHOR"<br />}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;<br />print_usage() {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo ""<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "$PROGNAME $RELEASE - Disk health check script for Nagios"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo ""<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "Usage: check_disk_health.sh -d /dev/sdb"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo ""<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "&nbsp; -d&nbsp; the disk (/dev/sda) "<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; not the Hard disk partition(sda2 is wrong)"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "&nbsp; -v&nbsp; check the version"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "&nbsp; -h&nbsp; Show this page"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo ""<br />&nbsp;&nbsp;&nbsp; echo "Usage: $PROGNAME"<br />&nbsp;&nbsp;&nbsp; echo "Usage: $PROGNAME --help"<br />&nbsp;&nbsp;&nbsp; echo ""<br />&nbsp;&nbsp;&nbsp; exit 0<br />}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;<br />print_help() {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print_usage<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo ""<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "This plugin will check disk health&nbsp; "<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo ""<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit 0<br />}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;<br /># Parse parameters<br /># 传递参数<br />while [ $# -gt 0 ]; do<br />&nbsp;&nbsp;&nbsp; case "$1" in<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -h | --help)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print_help<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit $STATE_OK<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -v | --version)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print_release<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit $STATE_OK<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -d | --disk)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; shift<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CHECK_DISK=$1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #判断磁盘是否存在<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if [ ! -b $CHECK_DISK ];then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "$CHECK_DISK is no exsit,Please change it "<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit $STATE_CRITICAL<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *)&nbsp; echo "Unknown argument: $1"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print_usage<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit $STATE_UNKNOWN<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esac<br />shift<br />done<br />&nbsp;<br />＃根据不同的操作进行不同的操作，这里暂时只支持Linux<br />case `uname` in<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Linux )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #最核心的部分 前面都是些脚本的基本功能 一个框架 因为第一个脚本牵扯到了很多东西，虽然功能很简单，<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #但折腾了我不少，在后面的分析中会具体说到 总之注意sudo用法 脚本一开始就有说哦<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DISK_HEALTH=`$SMARTCTL&nbsp; -H $CHECK_DISK | tail -1 | cut -d: -f2- `<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #DISK_HEALTH="OK"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DISK_INFO=`/usr/bin/sudo $SMARTCTL -i $CHECK_DISK | grep "Device:"`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if [ "$DISK_HEALTH" = " OK" ]|| [&nbsp; "$DISK_HEALTH" = " PASSED" ];then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "OK - $CHECK_DISK status is $DISK_HEALTH "<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #echo "OK - $CHECK_DISK status is $DISK_HEALTH | $DISK_INFO"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit $STATE_OK<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "CRITICAL - $CHECK_DISK status is $DISK_HEALTH "<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #echo "CRITICAL - $CHECK_DISK status is $DISK_HEALTH | $DISK_INFO"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit $STATE_CRITICAL<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fi<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo "UNKNOWN: `uname` not yet supported by this plugin. Coming soon !"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit $STATE_UNKNOWN<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esac4)运行脚本</p> <p style="text-indent: 2em">（注意：在最开始自己写的脚本是没有sudo的，以上脚本是已经调试过后的，还需要配置一些其它的东西，慢慢看吧）<br />给与脚本执行权限，手动执行</p> <p style="text-indent: 2em"># ./check_disk_health.sh<br />OK &#8211; /dev/sda status is&nbsp; OK</p> <p style="text-indent: 2em">結果正确了，其实这个时候，高兴得太早了。 我先不说问题、继续正常的一般流程。</p> <p style="text-indent: 2em">5、配置Nagios 调用插件</p> <p style="text-indent: 2em">1）在远程NRPE 被监控服务器上修改nrpe.conf<br /># vim /usr/local/nagios/etc/nrpe.cfg<br />添加 command[check_sda_health]=/usr/local/nagios/libexec/check_disk_health.sh -d /dev/sda<br />（注意这里了，先提醒下，这里是错误的，一般是正确的，是这个脚本的特殊性造成的）</p> <p style="text-indent: 2em">2）在Nagios 监控服务器上添加一些配置</p> <p style="text-indent: 2em">定义服务</p> <p style="text-indent: 2em">define service{<br />use&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Disk-Health<br />host_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DB-56<br />servicegroups&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Disk-Health<br />service_description&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; check sda disk health<br />contact_groups&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; admins<br />check_command&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; check_nrpe!check_sda_health<br />}<br />如果像上面定义一个服务 那么就要注意相关的定义了 ，<br />定义Disk-Health 模版&nbsp; 把硬盘检测定义一个模版会比较好控制，因为硬盘的检测不像其它服务一样需要准确的及时性反正检测得太多可能会造成压力，一般一天检测几次就够了。<br />定义DB-56 主机需要定义<br />定义组 admins<br />以上这些只要安装过nagios 一般都知道的了 只是强调下模版的单独定义</p> <p style="text-indent: 2em">3)通过WEB控制检测 查看結果</p> <p style="text-indent: 2em">結果是失败 报警CRITCTL 但是状态里面的信息都是空的&nbsp; CRITCTL &#8211; /dev/sda status is</p> <p style="text-indent: 2em">6、调试</p> <p style="text-indent: 2em">从Nagios的远程监控来看是失败的，并且没有获取到任务有用的信息。</p> <p style="text-indent: 2em">分析可以看到，说明nrpe调用&nbsp; 这个变量获取到的是为空的信息<br />DISK_HEALTH=`$SMARTCTL -H $CHECK_DISK | tail -1 | cut -d: -f2- `<br />即是空的 只有一个原因，肯定是没有执行 如果执行了 肯定会有字段 不管这个字段是否相符。<br />但是手动执行是没有问题。<br />经过对smartctl的查看 原来这个命令是只允许root进行调用的。<br />现在需要解决的问题是：非root 用户 如何远程调用含有需要有root权限命令的脚本进行监控。<br />（不要小看这一句话，每一个词都是一个需要攻克的地方）<br />以下是调试步骤：<br />1）非root用户<br />NRPE插件是用nagios这个用户来执行的 所以要得到真实的情况需要<br />A： su nagios&nbsp;&nbsp; 再执行脚本 (这个方法比较好)<br />B： sudo -u nagios ./check_disk_health.sh<br />結果：</p> <p style="text-indent: 2em">sudo -u nagios ./check_disk_health.sh<br />CRITICAL &#8211; /dev/sda status is<br />跟远程的結果是一样的了 没有信息<br />2）需要有root权限<br />需要root权限只有一个办法就是用sudo<br />将DISK_HEALTH=`$SMARTCTL -H $CHECK_DISK | tail -1 | cut -d: -f2- `<br />改为DISK_HEALTH=`/usr/bin/sudo $SMARTCTL -H $CHECK_DISK | tail -1 | cut -d: -f2- `<br />（最后发现这时加sudo 并不是关键 关键是很行脚本时用sudo ）<br />結果：sudo -u nagios ./check_disk_health.sh<br />Password:<br />需要输入密码&nbsp; sudo不用输入密码的方法<br />修改sudo配置文件<br />执行 visudo<br />添加<br />nagios ALL=(ALL) NOPASSWD:/usr/local/nagios/libexec/check_disk_health.sh<br />建议：最好进行sudo的一些控制，很多网方法就是nagios ALL=NOPASSWD:ALL<br />结果：<br />su nagios<br />/usr/bin/sudo check_disk_health.sh<br />OK &#8211; /dev/sda status is OK<br />那么在nrpe.conf配置文件中需要添加sudo<br />command[check_sda_health]=/usr/bin/sudo /usr/local/nagios/libexec/check_disk_health.sh<br />最开始那个是错误的 注意啊 这个是需要添加/usr/bin/sudo 就是说只要脚本中涉及到提升到root权限的命令那么就要用这个<br />3）远程调用<br />远程调用方法：./check_nrpe -H 192.168.0.56 -c check_sda_health<br />同上如果想模拟真实环境请切换到相应的执行用户 su nagios 再执行以上操作<br />结果：&nbsp;&nbsp; NRPE: Unable to read output<br />这个错误的原因一定要明白，之所以报这个错意思是说NRPE没有获取到任何信息，也说是写脚本之前说的其中第二条规范<br />问题：在没有任何信息的情况下怎么来获取NRPE执行的日志呢<br />就是要确定问题在哪，经过一大番的查找眼睛偶尔看到一个有趣的小方法<br />修复nrpe.conf配置文件 在要检查的命令后面添加&gt;&gt;/tmp/output 2&gt;&amp;1 将错误导出到文件中进行查看<br />command[check_sda_health]=/usr/bin/sudo  /usr/local/nagios/libexec/check_disk_health.sh -d /dev/sda  &gt;&gt;/tmp/output 2&gt;&amp;1<br />重记nrpe服务<br />远程调用 结果当然还是NRPE: Unable to read output<br />查看/tmp/output<br />sudo: sorry, you must have a tty to run sudo<br />有错误就简单了&nbsp; 原来这个是默认不允许sudo 在后端进行<br />visudo<br />注释Defaults requiretty 就OK了<br />结果通过WEB查看也正确了。<br />(注意：注释后 检测仍然会是Unable 不过看/tmp/output就会有正确的結果，所以有正确的結果后，一定要去掉 &gt;&gt;/tmp/outpt 2&gt;&amp;1 信息都导到文件中了 nagios还是得不到任何消息。)</p> <p style="text-indent: 2em">一个脚本执行成功后，就是大批量应用，用生产环境验证，出现问题继续调试。</p> 以上为所有的分析调试方法。如果你看到最后一步了，说明你很有耐心，你也一定会成功的，至于写得好与坏、对与错请尽管说，这不会影响你的成功。呵呵。</div>转自:<div>http://blog.chinaunix.net/uid-20592013-id-2436813.html</div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/202981.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2013-09-03 09:39 <a href="http://www.cppblog.com/guojingjia2006/archive/2013/09/03/202981.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux下Nagios的安装与配置</title><link>http://www.cppblog.com/guojingjia2006/archive/2013/09/02/202946.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Mon, 02 Sep 2013 06:26:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2013/09/02/202946.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/202946.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2013/09/02/202946.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/202946.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/202946.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一、Nagios简介  　　Nagios是一款开源的电脑系统和网络监视工具，能有效监控Windows、Linux和Unix的主机状态，交换机路由器等网络设置，打印机等。在系统或服务状态异常时发出邮件或短信报警第一时间通知网站运维人员，在状态恢复后发出正常的邮件或短信通知。 　　Nagios原名为NetSaint，由Ethan Galstad开发并维护至今。NAGIOS是一个缩写形式: "Nagio...&nbsp;&nbsp;<a href='http://www.cppblog.com/guojingjia2006/archive/2013/09/02/202946.html'>阅读全文</a><img src ="http://www.cppblog.com/guojingjia2006/aggbug/202946.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2013-09-02 14:26 <a href="http://www.cppblog.com/guojingjia2006/archive/2013/09/02/202946.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux 维护</title><link>http://www.cppblog.com/guojingjia2006/archive/2013/02/28/198133.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Thu, 28 Feb 2013 03:15:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2013/02/28/198133.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/198133.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2013/02/28/198133.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/198133.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/198133.html</trackback:ping><description><![CDATA[<div><p>SSH配置：</p> <p>1、修改vi&nbsp;/etc/ssh/sshd_config，根据模板将要修改的参数注释去掉并修改参数值：</p> <p>Port 22 指定SSH连接的端口号，安全方面不建议使用默认22端口</p> <p>Protocol 2,1 允许SSH1和SSH2连接，建议设置成 Protocal 2</p> <p>其他参数根据自己的需要进行调整。配置方法详见：&nbsp;man ssh_config</p> <p>2、修改hosts.deny 在最后面添加一行：</p> <p>sshd:All</p> <p>3、修改hosts.allow 在最后面添加一行：</p> <p>sshd:All</p> <p>如果为了安装可以限制访问的IP，设置如下：</p> <p>sshd:192.168.0.101</p> <p>sshd:192.168.0.102</p> <p>上述配置表示只允许101和102的服务器进行SSH连接</p> <p>4、启动SSH</p> <p>/etc/init.d/sshd start</p></div><br /><div># chkconfig --list |grep sshd<br /><div>sshd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0:off&nbsp;&nbsp; 1:off&nbsp;&nbsp; 2:on&nbsp;&nbsp;&nbsp; 3:on&nbsp;&nbsp;&nbsp; 4:on&nbsp;&nbsp;&nbsp; 5:on&nbsp;&nbsp;&nbsp; 6:off</div></div><div>#chkconfig --level 2345 sshd on<br /><br />iptables<br /><div># Generated by iptables-save v1.4.7 on Tue Feb&nbsp; 7 19:06:20 2012<br />*filter<br />:INPUT ACCEPT [100:10222]<br />:FORWARD ACCEPT [0:0]<br />:OUTPUT ACCEPT [75:7016]<br />-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT<br />-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT<br />COMMIT<br /># Completed on Tue Feb&nbsp; 7 19:06:20 2012</div><br /><br /><div><div>（1）屏蔽所有端口&nbsp;</div> <div>（2）把SSH的缺省端口设置为56565&nbsp;</div> <div>（3）把56565、80、3306端口打开&nbsp;</div> <div>（4）把3306端口设置为只允许本机访问</div> <div>&nbsp;</div> <div>如果没有安装iptables的话，运行命令yum install iptables完成iptables安装</div> <div>&nbsp;</div> <div>初始化安装以后，显示为以下信息：</div> <div>&nbsp;</div> <div>[root@tp ~]# iptables -L -n</div> <div>&nbsp;</div> <div>Chain INPUT (policy ACCEPT)</div> <div>&nbsp;</div> <div>target prot opt source destination</div> <div>&nbsp;</div> <div>Chain FORWARD (policy ACCEPT)</div> <div>&nbsp;</div> <div>target prot opt source destination</div> <div>&nbsp;</div> <div>Chain OUTPUT (policy ACCEPT)</div> <div>&nbsp;</div> <div>target prot opt source destination</div> <div>（1）屏蔽所有端口</div> <div>&nbsp;</div> <div>[root@tp ~]# iptables -F</div> <div>[root@tp ~]# iptables -X</div> <div>[root@tp ~]# iptables -P INPUT DROP</div> <div>[root@tp ~]# iptables -P OUTPUT DROP</div> <div>[root@tp ~]# iptables -P FORWARD DROP</div> <div>当超出了IPTABLES里filter表里的两个链规则  (INPUT,FORWARD)时,不在这两个规则里的数据包怎么处理呢,那就是DROP(放弃)，有同学喜欢配置OUTPUT为accpet，因为如果 被入侵，对方可以使用服务器做为中转，发起攻击，也会产生大量的数据包，所以这里配置为DROP</div> <div>&nbsp;</div> <div>（2）把SSH的缺省端口设置为56565</div> <div>&nbsp;</div> <div>在修改ssh端口时，应先把要修改的端口号56565加入白名单</div> <div>&nbsp;</div> <div>[root@tp ~]# iptables -A INPUT -p tcp --dport 56565 -j ACCEPT</div> <div>[root@tp ~]# iptables -A OUTPUT -p tcp --sport 56565 -j ACCEPT</div> <div>[root@tp ~]# /etc/rc.d/init.d/iptables save</div> <div>[root@tp ~]# service iptables restart</div> <div>再修改端口号</div> <div>&nbsp;</div> <div>[root@linux ~]# vi /etc/ssh/sshd_config</div> <div>将"#Port 22"修改为"Port 56565"</div> <div>&nbsp;</div> <div>重启ssh服务</div> <div>&nbsp;</div> <div>[root@linux ~]# /etc/init.d/sshd restart</div> <div>Stopping sshd: [ OK ]</div> <div>Starting sshd: [ OK ]</div> <div>如果想看看sshd端口号是否修改成功的话，可以使用 netstat -an 命令查看一下或退出ssh使用新端口号登陆尝试。</div> <div>&nbsp;</div> <div>（3）把80端口打开</div> <div>&nbsp;</div> <div>[root@tp ~]# iptables -A INPUT -p tcp --dport 80 -j ACCEPT</div> <div>[root@tp ~]# iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT</div> <div>[root@tp ~]# /etc/rc.d/init.d/iptables save</div> <div>[root@tp ~]# service iptables restart</div> <div>（4）把3306端口设置为只允许本机访问</div> <div>&nbsp;</div> <div>[root@tp ~]#/sbin/iptables -A INPUT -p tcp -s 127.0.0.1 --dport 3306 -j ACCEPT</div> <div>[root@tp ~]#/sbin/iptables -A OUTPUT -p tcp -s 127.0.0.1 --dport 3306 -j ACCEPT<br /><br /><div>http://gzjhj88.blog.51cto.com/1049760/629563<br /><div>http://www.redicecn.com/html/qita/20110331/243.html</div><div>http://wenku.baidu.com/view/94fadf1252d380eb62946d95.html<br /><br /><div>http://www.bugbeta.cn/?p=495</div><div>http://gzjhj88.blog.51cto.com/1049760/629563</div><div>http://gzjhj88.blog.51cto.com/1049760/315021</div></div></div></div></div></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/198133.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2013-02-28 11:15 <a href="http://www.cppblog.com/guojingjia2006/archive/2013/02/28/198133.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[CyanogenMOD移植教程]第二章：android 源码总体结构 (转)</title><link>http://www.cppblog.com/guojingjia2006/archive/2013/02/20/197952.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Wed, 20 Feb 2013 06:16:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2013/02/20/197952.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/197952.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2013/02/20/197952.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/197952.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/197952.html</trackback:ping><description><![CDATA[<div><div style="text-indent: 2em;">&#8211; Makefile (全局的Makefile文件)</div> <div style="text-indent: 2em;">&#8211; bionic (Bionic含义为仿生,这里面是一些基础的C库源代码)</div> <div style="text-indent: 2em;">&#8211; bootloader (引导加载器)</div> <div style="text-indent: 2em;"> build目录中的内容不是目标所用的代码,而是编译和配置所需要的脚本和工具)</div> <div style="text-indent: 2em;">&#8211; build (build目录中的内容不是目标所用的代码,而是编译和配置所需要的脚本和工具)</div> <div style="text-indent: 2em;">&#8211; cts (Android兼容性测试套件标准)</div> <div style="text-indent: 2em;">&#8211; libcore (核心库相关)</div> <div style="text-indent: 2em;">Dalvik虚拟机 针对嵌入式设备优化的Java</div> <div style="text-indent: 2em;">Java虚拟机)</div> <div style="text-indent: 2em;">&#8211; dalvik ( Dalvik虚拟机,针对嵌入式设备优化的Java虚拟机)</div> <div style="text-indent: 2em;">&#8211; development (创建应用程序所需要的模板和工具)</div> <div style="text-indent: 2em;">qcom,</div> <div style="text-indent: 2em;">&#8211; device (与具体设备相关的一些编译脚本和库,如htc,qcom,samsung等)</div> <div style="text-indent: 2em;">&#8211; external (Android使用的一些外部的开源框架和库)</div> <div style="text-indent: 2em;">(应用程序的框架层,SDK</div> <div style="text-indent: 2em;">SDK的接口基本都是在这里实现的)</div> <div style="text-indent: 2em;">&#8211; frameworks (应用程序的框架层,SDK的接口基本都是在这里实现的)</div> <div style="text-indent: 2em;">&#8211; hardware (与硬件相关的库)</div> <div style="text-indent: 2em;">Linux2.6</div> <div style="text-indent: 2em;">&#8211; kernel (Linux2.6的内核源代码)</div> <div style="text-indent: 2em;">&#8211; ndk (本地开发套件--C语言开发套件)</div> <div style="text-indent: 2em;">--C</div> <div style="text-indent: 2em;">Android的各种应用程序)</div> <div style="text-indent: 2em;">&#8211; packages (Android的各种应用程序)</div> <div style="text-indent: 2em;">&#8211; prebuilt (Android在各种平台下编译的预置脚本)</div> <div style="text-indent: 2em;">&#8211; sdk (SDK及模拟器)</div> <div style="text-indent: 2em;">Android的底层的一些库)</div> <div style="text-indent: 2em;">&#8211; system (Android的底层的一些库)</div> <div style="text-indent: 2em;">`&#8211; vendor (厂商私有的代码)</div> <div style="text-indent: 2em;"></div> <div style="text-indent: 2em;"></div> <div style="text-indent: 2em;">~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</div> <div style="text-indent: 2em;"> <div>packages/</div> <div>|&#8211; apps (各种应用程序,如联系人、浏览器等)</div> <div>|&#8211; experimental (一些实验性的项目,如错误报告)</div> <div>|&#8211; inputmethods (输入法相关)</div> <div>|&#8211; providers (各种数据源实现,如联系人数据、媒体库等信息)</div> <div>|&#8211; wallpapers (各种壁纸程序)</div> </div> <div style="text-indent: 2em;"></div> <div style="text-indent: 2em;"> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</div>  <div style="text-indent: 2em;">Android Framework功能介绍</div> <div style="text-indent: 2em;">android.app :提供高层的程序模型和基本的运行环境。</div> <div style="text-indent: 2em;">android.content :包含对各种设备上的数据进行访问和发布。</div> <div style="text-indent: 2em;">android.database :通过内容提供者浏览和操作数据库。</div> <div style="text-indent: 2em;">android.graphics :底层图形库,包含画布、点、矩形等,可以将其直接绘制到屏幕上。</div> <div style="text-indent: 2em;">android.location :定位和相关服务的类。</div> <div style="text-indent: 2em;">android.media :提供一些类管理多种音频、视频的媒体接口。</div> <div style="text-indent: 2em;">android.net :提供帮助网络访问的类,超过通常的 java.net.* 接口。</div> <div style="text-indent: 2em;">android.os :提供了系统服务、消息传输和 IPC 机制。</div> <div style="text-indent: 2em;">android.opengl :提供 OpenGL 的工具。</div> <div style="text-indent: 2em;">android.provider :提供访问 Android 内容提供者的类。</div> <div style="text-indent: 2em;">android.telephony :提供与拨打电话相关的 API 交互。</div> <div style="text-indent: 2em;">android.view :提供基础的用户界面接口框架。</div> <div style="text-indent: 2em;">android.util :涉及工具性的方法,例如时间日期的操作。</div> <div style="text-indent: 2em;">android.webkit :默认浏览器操作接口。</div> <div style="text-indent: 2em;">android.widget :包含各种 UI 元素(大部分是可见的)在应用程序的布局中使用</div> <div>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</div> <div> <div>build/</div> <div>|&#8211; buildspec.mk.default</div> <div>|&#8211; cleanspec.mk</div> <div>|&#8211; core (各种以mk为结尾的文件,它门是编译所需要的Makefile)</div> <div>|&#8211; envsetup.sh</div> <div>|&#8211; libs</div> <div>|&#8211; target (包含board和product两个目录,为目标所需要文件)</div> <div>|&#8211; tools (编译过程中主机所需要的工具,一些需要经过编译生成)</div> <div>其中,core中的Makefile是整个Android编译所需要的真正的<span style="text-indent: 2em;">Makefile,它被顶层目录的Makefile引用。</span></div> <div></div> </div> <div></div> <div>基本介绍到此，文章参考网络中各种文章，如果有侵权啥行为的，请联系删除。</div></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/197952.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2013-02-20 14:16 <a href="http://www.cppblog.com/guojingjia2006/archive/2013/02/20/197952.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Linux Mint 13 的安装、配置及搭建Android源码编译环境(转)</title><link>http://www.cppblog.com/guojingjia2006/archive/2013/02/19/197940.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Tue, 19 Feb 2013 09:06:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2013/02/19/197940.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/197940.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2013/02/19/197940.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/197940.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/197940.html</trackback:ping><description><![CDATA[<div><p>用过ubuntu，现在想换换LinuxMint试试看。下面是我安装配置LinuxMint13的过程。</p> <h1>1、安装</h1> <p>安装LinuxMint13时，我尝试了好多种方法，都失败了。最后选用了硬盘安装。硬盘安装Linuxmint和安装ubuntu一样。</p> <h2>1.1、准备工作</h2> <p>1、从linux mint的官方网站<a href="http://www.linuxmint.com/">http://www.linuxmint.com/</a> 下载linux mint 13。</p> <p>2、下载grub4dos，<a href="http://www.linuxidc.com/Linux/2009-01/18027.htm">http://www.linuxidc.com/Linux/2009-01/18027.htm</a> 。</p> <h2>1.2、安装步骤</h2> <p>1、将下载的linuxmint-13-mate-dvd-64bit.iso 拷贝到系统的C盘根目录。</p> <p>2、从linuxmint-13-mate-dvd-64bit.iso的<span style="color: #ff0000;">casper</span>文件夹中提取出<span style="color: #ff0000;">vmlinuz、initrd.lz</span>文件。也放到C盘根目录下。</p> <p>3、解压grub4dos压缩包，会得到一个名为grub4dos-0.4.4的文件夹，将以下文件拷贝到C盘（其中前两个文件是必需的，后两个文件网上有些资料说不需要，为了保险起见还是放上吧，反正也没什么坏处～）：</p> <p>　　<span style="color: #ff0000;"><strong>grldr</strong></span>　<span style="color: #ff0000;"><strong>menu.lst</strong></span>　 grldr.mbr　 grub.exe</p> <p>4、修改menu.lst文件，在文件末尾添加以下内容</p> <blockquote> <p>title <strong>Install <a title="Ubuntu" href="http://www.linuxidc.com/topicnews.aspx?tid=2">Linux Mint</a></strong></p> <p>root (hd0,0)</p> <p>kernel (hd0,0)/vmlinuz boot=casper iso-scan/filename=/<strong>linuxmint-13-mate-dvd-64bit.iso</strong> locale=zh_CN.UTF-8</p> <p>initrd (hd0,0)/initrd.lz</p> </blockquote> <p>&nbsp;其中，title后面的内容随便写就是，kernel后面的那个突出显示的就是<a title="Ubuntu" href="http://www.linuxidc.com/topicnews.aspx?tid=2">Linux Mint</a>的镜像文件，需要与C盘中的文件名对应。</p> <p>5、修改C盘根目录下隐藏的boot.ini，打开文件后，在文件最后添加如下内容</p> <p>　　c:\grldr=&#8221;<a title="Ubuntu" href="http://www.linuxidc.com/topicnews.aspx?tid=2">Linux Mint</a> Install&#8221;</p> <p>以上工作完成后，重启系统即可开始XP硬盘安装<a title="Ubuntu" href="http://www.linuxidc.com/topicnews.aspx?tid=2">Linux Mint</a>的过程了！</p> <p>&nbsp;</p> <p>不过我安装花了好长的时候，时间主要是浪费在系统分区上了，每个分区的操作都要等上好久啊，蛋疼啊！</p> <p><span style="color: #ff0000;">注意：在重启后进入Linux Mint界面后就先卸载isodevices</span></p> <p><span style="color: #ff0000;">　　umount -l /isodevices</span></p> <p><span style="color: #ff0000;">这步很重要，未执行这步，分区无法成功。<br /></span></p> <p>&nbsp;</p> <h1>2、配置</h1> <p>安装完成之后可以进行配置了，由于安装是没有链接到网络，也就没有下载更新包、语言包。现在首要的就是进行安装语言包。</p> <p>MINT 13默认的更新源是真心慢啊，所以第一步要先处理更新源的问题。</p> <h2>2.1、更新源</h2> <p>LinuxMint 的镜像建立在中国科技大学的镜像站上了，中国科技大学 LinuxMint:<a href="http://mirrors.ustc.edu.cn/linuxmint/" target="_blank">http://mirrors.ustc.edu.cn/linuxmint/ </a>这是唯一也是主镜像。</p> <p>下面就说一下具体步骤</p> <p>1、登录 Linux Mint,打开终端。</p> <p>2、键入命令 sudo nano /etc/apt/sources.list，建议先备份下。</p> <p>3、打开文本后应该是这个样子<br /> deb http://packages.linuxmint.com/ maya main upstream import<br />deb http://archive.ubuntu.com/ubuntu/ precise main restricted universe multiverse<br />deb http://archive.ubuntu.com/ubuntu/ precise-updates main restricted universe multiverse<br />deb http://security.ubuntu.com/ubuntu/ precise-security main restricted universe multiverse<br />deb http://archive.canonical.com/ubuntu/ precise partner<br />deb http://packages.medibuntu.org/ precise free non-free<br />可以看出没有中国服务器的影子</p> <p>4、下面我们就来添加中国的源<br /> 添加以下文字<br /> deb http://mirrors.ustc.edu.cn/linuxmint/ maya main upstream import universe multiverse<br />deb http://mirrors.163.com/ubuntu/ precise main restricted universe multiverse<br />deb http://mirrors.163.com/ubuntu/ precise-security main restricted universe multiverse<br />deb http://mirrors.163.com/ubuntu/ precise-updates main restricted universe multiverse<br />并且将原来的源全部注释掉(就是封掉,不要用了)<br /> deb http://packages.linuxmint.com/ maya main upstream import<br />deb http://archive.ubuntu.com/ubuntu/ precise main restricted universe multiverse<br />deb http://archive.ubuntu.com/ubuntu/ precise-updates main restricted universe multiverse<br />deb http://security.ubuntu.com/ubuntu/ precise-security main restricted universe multiverse<br />deb http://archive.canonical.com/ubuntu/ precise partner<br />deb http://packages.medibuntu.org/ precise free non-free<br /> 注意就是在最前面多加了个#号即可<br /> 注:这里以 Linux Mint 13 maya 为例,其它举一反三即可。其实就是改个链接而已。后<br /> 面的文字保持原样即可。</p> <p>5、更新 APT<br /> 在终端输入命令 sudo apt-get update<br /> 等待执行完成即可。这时你会发现 Linux Mint 原来如此轻盈!</p> <p>&nbsp;</p> <h2>2.2、安装输入法</h2> <p>在这里我安装的是FCITX</p> <p>直接从软件管理器中搜索fcitx，然后安装。</p> <p>安装完成后到 控制中心 ---》Language Support 的键盘输入方式系统中选择fictx </p> <p>重启系统即可使用。</p> <p>&nbsp;</p> <h2>&nbsp;2.3、安装QQ</h2> <p>1、到以下网址下载deb安装包，<a href="http://www.longene.org/download/qq2011-for-wine_20120220.deb">http://www.longene.org/download/qq2011-for-wine_20120220.deb</a>，已经打包好的deb包，大小为150M左右；</p> <p><span style="color: #ff0000;">　　最新发布 6-1 号更新的 ：</span><a href="http://www.longene.org/download/WineQQ2012-20120531-Longene.deb"><span style="color: #ff0000;">http://www.longene.org/download/WineQQ2012-20120531-Longene.deb</span></a><span style="color: #ff0000;"> 有几个bug 已经修补啦 ！</span></p> <p>2、打开终端输入到目录中运行命令安装：</p> <p>　　sudo dpkg -i *.deb</p> <p>3、64位系统还需要运行以下命令：</p> <p>　　sudo apt-get install ia32-libs</p> <p>4、卸载的话运行以下命令：</p> <p>　　dpkg -r qq-for-wine</p> <p>&nbsp;</p> <h2><span style="color: #000000;">2.4、安装Google Chrome<br /></span></h2> <p><span style="color: #000000;">1、chrome</span></p> <p><span style="color: #000000;">到<a href="https://www.google.com/intl/en/chrome/browser/index.html">https://www.google.com/intl/en/chrome/browser/index.html</a> 下载最新的安装包。也可以通过下面的命令安装<br /></span></p> <p>32位系统：</p> <p>wget -O google-chrome_i386.deb <a href="http://goo.gl/itppy">http://goo.gl/itppy</a></p> <p>sudo dpkg -i google-chrome_i386.deb</p> <p>64位系统：</p> <p>wget -O google-chrome_amd64.deb http://goo.gl/iXDWk</p> <p>sudo dpkg -i google-chrome*.deb</p> <p>2、chromium</p> <p>sudo apt-get install chromium-browser</p> <p>chromium flash 插件失效的修复方法：</p> <p>　　查找flash插件</p> <p>　　　　$ sudo locate libflashplayer.so</p> <p>　　　　/usr/lib/adobe-flashplugin/libflashplayer.so</p> <p>　　拷贝flash插件到chromium-browser插件目录<br />　　　　$ sudo cp /usr/lib/adobe-flashplugin/libflashplayer.so <span style="color: #ff0000;">/usr/lib/chromium-browser/plugins</span></p> <p>&nbsp;</p> <h2><span style="color: #000000;">2.5、安装无线网卡</span></h2> <p><span style="color: #000000;">我的网卡是BCM4312，在网上找了好久，试过两三种方法都不行。最后找到以下方法解决：</span></p> <p><span style="color: #000000;">1、<span>先到Broadcom的官方网站去仔细的看看说明具体链接地址如下：<br /><a title="" href="http://www.broadcom.com/support/802.11/linux_sta.php" target="_blank">http://www.broadcom.com/support/802.11/linux_sta.php</a></span></span></p> <p><span style="color: #000000;">可以先查看自己的网卡的型号，下载对应的驱动。<span>在终端下输入：&#8220;lspci | grep Network" 确认网卡型号。</span></span></p> <p><span style="color: #000000;"><span>2、<span>解压缩<br />tar -xzf hybrid-portsrc-x86_32-v5.60.48.36.tar.gz</span></span></span></p> <p><span style="color: #000000;"><span><span>3、编译<br />make</span></span></span></p> <p><span style="color: #000000;"><span><span>编译时遇到下面的错误：</span></span></span></p> <p>/home/lgq/hybrid_wl/src/wl/sys/wl_linux.c:388:2: 错误： 初始值设定项里有未知的字段&#8216;ndo_set_multicast_list&#8217;<br />/home/lgq/hybrid_wl/src/wl/sys/wl_linux.c:388:2: 警告： 从不兼容的指针类型初始化 [默认启用]<br />/home/lgq/hybrid_wl/src/wl/sys/wl_linux.c:388:2: 警告： (在&#8216;wl_netdev_ops.ndo_validate_addr&#8217;的初始化附近) [默认启用]</p> <p><span style="color: #000000;">在google后发现 <span style="color: #ff0000;">&nbsp;ndo_set_multicast_list</span> 被<span style="color: #ff0000;">ndo_set_rx_mode</span>替换(在以下网站提到<a href="http://www.mindwerks.net/2011/11/wireless-bcm4312-3-2-kernel/">http://www.mindwerks.net/2011/11/wireless-bcm4312-3-2-kernel/</a></span></p> <p><span style="color: #000000;">再次编译通过。</span></p> <p><span style="color: #000000;">4、sudo make install</span></p> <p><span style="color: #000000;">5、sudo depmod</span></p> <p><span style="color: #000000;">6、sudo modprobe wl</span></p> <p><span style="color: #000000;"><span><span>Give Ubuntu a few seconds  after loading the &#8220;wl&#8221; kernel module, then eventually the Network  Manager will start looking for wireless networks.</span></span></span></p> <p><span style="color: #000000;">&nbsp;</span></p> <p><span style="color: #000000;">参考链接：<a href="http://blog.csdn.net/cs090506/article/details/7300526">http://blog.csdn.net/cs090506/article/details/7300526</a></span></p> <p><span style="color: #000000;">&nbsp;</span></p> <h2><span style="color: #000000;">2.6、安装词典星际译王</span></h2> <p>通过软件管理器安装星际译王stardict。</p> <p>词典下载路径：<a href="http://abloz.com/huzheng/stardict-dic/">http://abloz.com/huzheng/stardict-dic/</a></p> <p>&nbsp;</p> <h2><span style="color: #000000;">2.7、</span>编译安装最新的alsa驱动</h2> <p>刚安装好的linux mint，插上耳机后，笔记本的内置音箱仍然还有声音。</p> <p>1、查看自己声卡的codec型号。</p> <p>终端输入alsamixer，查看显示的chip值。或者<span>cat /proc/asound/card0/codec#0，查看显示结果的首行。</span></p> <p>2、到官方网站下载相应的驱动来安装。</p> <p>&nbsp;</p> <h1><span style="color: #000000;">3、搭建Android源码开发环境</span></h1> <p><span style="color: #000000;">在本节搭建的是Android4.0的源码开发环境。</span></p> <p><span style="color: #000000;">Linux Mint 13 中已经安装了 GNU Make 3.81、Python 2.7.3、Git 1.7.9.5。</span></p> <p><span style="color: #000000;">所以还需要安装jdk6。</span></p> <h2><span style="color: #000000;">3.1、安装jdk6</span></h2> <p><span style="color: #000000;">Linux Mint 13 中自带有OpenJDK，但这个不是我想要的，我们要的是sun-java6。</span></p> <p><span style="color: #000000;">1、在安装sun的jdk前，先删除OpenJDK，打开新立得，搜索OpenJDK，彻底删除所有的包。</span></p> <p><span style="color: #000000;">2、在sun的官网上<a href="http://www.oracle.com/technetwork/java/javase/downloads/jdk6-downloads-1637591.html">http://www.oracle.com/technetwork/java/javase/downloads/jdk6-downloads-1637591.html</a>&nbsp;下载最新的<span>安装文件（<span>如：jdk-6u34-linux-x64.bin）。</span></span></span></p> <p><span style="color: #000000;"><span>增加执行权限：sudo chmod u+x jdk-6u34-linux-x64.bin</span></span></p> <p><span style="color: #000000;">将安装文件拷贝到&nbsp;/usr/lib/java/ 目录下</span></p> <p><span style="color: #000000;">执行安装命令 &nbsp;<span style="color: #ff0000;">./jdk-6u34-linux-x64.bin</span></span></p> <p>&nbsp;成功安装完JDK后，接下来我们将要进行ＪＤＫ的配置，使用命　<strong>$ sudo gedit /etc/environment</strong>　对environment文件进行修改并添加以下代码：</p> <p><span style="color: #888888;">&nbsp;　　　　PATH＝"/usr/lib/java/jdk1.6.0_34/bin"&nbsp;&nbsp;</span></p> <p><span style="color: #888888;">　　　　CLASSPATH="/usr/lib/java/jdk1.6.0_34/lib"</span></p> <p><span style="color: #888888;">　　　　JAVA_HOME=<span>"/usr/lib/java/jdk1.6.0_34"</span>&nbsp;&nbsp;&nbsp;</span></p> <p>&nbsp;若PATH已存在，则用冒号作间隔，将jdk的bin目录地址加上，这样java的环境变量将配置成功了，但这样默认使用的JDK可能还不是我们  刚才安装的，因为ubuntu可能还会有默认的jdk，如openjdk；所以，为了使默认使用的是我们安装的jdk，还需执行如下命令:</p> <p>&nbsp;　　　　$&nbsp;sudo&nbsp;update-alternatives&nbsp;--install&nbsp;/usr/bin/java&nbsp;java&nbsp;/usr/lib/java/jdk1.6.0_34/bin/java&nbsp;300</p> <p>　　　　$&nbsp;sudo&nbsp;update-alternatives&nbsp;--install&nbsp;/usr/bin/javac&nbsp;javac&nbsp;/usr/lib/java/jdk1.6.0_34/bin/javac&nbsp;300&nbsp;</p> <p><span>　　　　$&nbsp;sudo&nbsp;update-alternatives&nbsp;--config&nbsp;java&nbsp;&nbsp;&nbsp;&nbsp;<br /></span></p> <p>&nbsp;成功执行命令后，我们安装的JDK就是系统默认的了，执行命令&nbsp;$&nbsp;java&nbsp;-version&nbsp;&nbsp;就可以成功看到 JDK的相关信息了如：</p> <p>&nbsp;　　　　java version "1.6.0_34"</p> <p>　　　　Java(TM) SE Runtime Environment (build 1.6.0_34-b04)<br />　　　　Java HotSpot(TM) 64-Bit Server VM (build 20.9-b04, mixed mode)&nbsp;&nbsp;</p> <h2><span style="color: #000000;">&nbsp;3.2、安装必需的软件包</span></h2> <p>&nbsp;安装编译Android需要的工具包，这个步骤是关键，必须安装，否则编译会报莫名其妙的错误！！！！！！！！！！！！！！！！</p> <p><span>sudo apt-get install git-core gnupg flex bison gperf  build-essential&nbsp;&nbsp; zip curl zlib1g-dev libc6-dev lib32ncurses5-dev  ia32-libs&nbsp;&nbsp; x11proto-core-dev libx11-dev lib32readline-gplv2-dev  lib32z1-dev&nbsp;&nbsp; libgl1-mesa-dev gcc-multilib g++-multilib mingw32 tofrodos  python-markdown&nbsp;&nbsp; libxml2-utils&nbsp; xsltproc</span>&nbsp;</p> <h2><span style="color: #000000;">3.3、配置USB</span></h2> <p>lgq-laptop bin # lsusb<br />Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub<br />Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub<br />Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub<br />Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub<br />Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub<br />Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub<br />Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub<br />Bus 002 Device 003: ID 04f2:b008 Chicony Electronics Co., Ltd USB 2.0 Camera<br />Bus 006 Device 002: ID 1ea7:000b &nbsp;<br />Bus 002 Device 004: ID 05c6:9025 Qualcomm, Inc. <br /><br /></p> <p>$sudo vim /etc/udev/rules.d/70-android.rules</p> <p>增加下面内容</p> <p>SUBSYSTEM=="usb", ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="9025",MODE="0666"</p> <p>运行命令，重启udev：</p> <p>$sudo chmod a+rx /etc/udev/rules.d/70-android.rules<br />$sudo service udev restart</p> <p>&nbsp;</p> <h2><span style="color: #000000;">3.4、安装svn</span></h2> <p>1、安装subversion</p> <p>apt-get install subversion</p> <p>2、安装rabbitvcs</p> <p><code>sudo add-apt-repository ppa:rabbitvcs/ppa</code></p> <p>sudo apt-get update</p> <p>sudo apt-get install rabbitvcs-nautilus3</p> <p>nautilus -q</p> <p>nautilus</p> <p>rabbitvcs的界面比较习惯，但是，很卡。</p> <p>3、rapidsvn</p> <p>sudo apt-get install rapidsvn</p> <p>4、esvn</p> <p>&nbsp;</p> <h2>3.5、设置ccache</h2> <div>&#9312;安装ccache</div> <div>官网下载或apt安装&nbsp; sudo apt-get install ccache</div> <div>&nbsp;</div> <div>&#9313;$ which ccache</div> <div>查看安装路径, /usr/bin/ccache</div> <div>&nbsp;</div> <div>&#9314;$ mkdir ~/.bin</div> <div>&#9315; $ cd ~/.bin/</div> <div>&nbsp;&nbsp; $ ln -s /usr/bin/ccache gcc</div> <div>&nbsp;&nbsp;&nbsp;$ ln -s /usr/bin/ccache g++</div> <div>&nbsp;&nbsp;&nbsp;$ ln -s /usr/bin/ccache arm-linux-gcc</div> <div>&nbsp;&nbsp;&nbsp;$ ln -s /usr/bin/ccache&nbsp;arm-linux-g++</div> <div>&nbsp;</div> <div>&#9316;PATH设置，将~/.bin/放在&nbsp;arm-linux-gcc等的PATH的前面。</div> <div>原：PATH=/usr/local/arm-linux_pre4/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin</div> <div>现：PATH=<span style="color: #ff0102;">/home/&lt;user&gt;/.bin</span>:/usr/local/arm-linux_pre4/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin</div> <div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gedit ~/.bashrc 添加 export PATH="/home/&lt;user&gt;/.bin:$PAHT" ，然后重启即可</div> <div>&nbsp;</div> <div> <div>&#9317;$ which&nbsp;arm-linux-gcc</div> <div>/home/&lt;user&gt;/.bin/arm-linux-gcc 确认</div> <div>&nbsp;</div> <div>&#9318;$ ccache -M 30G</div>                 </div> <p>&nbsp;</p> <h2>&nbsp;3.6、安装最新的eclipse</h2> <p>&nbsp;eclipse搭建方法参考：<a href="http://www.cnblogs.com/tnxk/archive/2012/07/09/2583800.html">http://www.cnblogs.com/tnxk/archive/2012/07/09/2583800.html</a></p> <p>eclipse的更新速度相当慢，这里收集一个加快更新的方法。</p> <p>解决办法只能是更换到Mirror站点，具体步骤：</p> <p>1.找个国内的站点-北方交通大学的不错<a href="http://mirror.bjtu.edu.cn/eclipse">http://mirror.bjtu.edu.cn/eclipse</a></p> <p>2.更换Eclipse更新服务器下载站点Windows -&gt; Preferences -&gt; Install/Update -&gt; Available Software Sites</p> <p>3.找到<strong>所有 The Eclipse&nbsp;</strong>开始的行，注意是<strong>所有的,</strong>因为不同版本的Eclipse官方项目比如 Web Tools Project，也都需要更改为镜像站点，否则将导致只有部分插件的站点得到更新，只能部分解决速度问题。</p> <p>4.点击&#8220;Edit&#8221;, 编辑Location部分，替换http://download.eclipse.org为<a href="http://mirror.bjtu.edu.cn/eclipse">http://mirror.bjtu.edu.cn/eclipse</a></p> <p>&nbsp;</p> <p>参考链接：<a href="http://blog.csdn.net/chenxihua/article/details/6423168">http://blog.csdn.net/chenxihua/article/details/6423168</a></p> <p>&nbsp;</p> <h1>4、问题及解决方法</h1> <h2>4.1、重启后出现&nbsp;waiting&nbsp;for&nbsp;network&nbsp;configuration&nbsp;问题</h2> <div><span><span>如今在 ubuntu 12.04 环境下接着拨号时，如果使用&nbsp;</span></span>sudo pppoeconf&nbsp;命令配置拨号，重启电脑后就会先显示 <span style="color: #ed1c24;">waiting for network configuration，然后是 <span style="color: #ed1c24;">waiting up to 60 more seconds for network configuration，</span>最后显示<span style="color: #ed1c24;">booting system without full network configuration.</span></span>并且进入桌面后网络连接状态图标也不见了。</div> <div><span style="color: #ffcc00; font-family: Arial;"><strong>问题原因：</strong></span></div>  <p><span><span>使用&nbsp;</span></span>sudo pppoeconf&nbsp;命令<span><span>时，会有信息写入</span><span style="font-family: Verdana, sans-serif;"><span><span>/etc/network/interfaces</span></span></span>&nbsp;<span>文件内，直接导致出现了上面的问题。</span></span></p> <p><span style="color: #ffcc00;"><strong>问题解决：</strong></span></p> <p>sudo gedit /etc/network/interfaces &nbsp;打开文件后，<span>将其中除</span></p> <p><strong>auto lo</strong></p> <p><span><span><span style="color: #6f3198;"><strong><span>iface lo inet loopback</span></strong></span><br /></span></span><span>外其他内容全部删除后，重启系统就可以了。</span></p></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/197940.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2013-02-19 17:06 <a href="http://www.cppblog.com/guojingjia2006/archive/2013/02/19/197940.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux 信号详解</title><link>http://www.cppblog.com/guojingjia2006/archive/2013/01/13/197232.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Sun, 13 Jan 2013 04:31:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2013/01/13/197232.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/197232.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2013/01/13/197232.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/197232.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/197232.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一 信号的种类 可靠信号与不可靠信号, 实时信号与非实时信号 可靠信号就是实时信号, 那些从UNIX系统继承过来的信号都是非可靠信号, 表现在信号 不支持排队,信号可能会丢失, 比如发送多次相同的信号, 进程只能收到一次. 信号值小于 SIGRTMIN的都是非可靠信号. 非可靠信号就是非实时信号, 后来, Linux改进了信号机制, 增加了32种新的信号, 这些信 号都是可靠信号, 表现在信号支持...&nbsp;&nbsp;<a href='http://www.cppblog.com/guojingjia2006/archive/2013/01/13/197232.html'>阅读全文</a><img src ="http://www.cppblog.com/guojingjia2006/aggbug/197232.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2013-01-13 12:31 <a href="http://www.cppblog.com/guojingjia2006/archive/2013/01/13/197232.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>写出健壮的 Bash 脚本</title><link>http://www.cppblog.com/guojingjia2006/archive/2013/01/09/197146.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Wed, 09 Jan 2013 04:11:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2013/01/09/197146.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/197146.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2013/01/09/197146.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/197146.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/197146.html</trackback:ping><description><![CDATA[<div><p>许多人用shell脚本完成一些简单任务，而且变成了他们生命的一部分。不幸的是，shell脚本在运行异常时会受到非常大的影响。在写脚本时将这类问题最小化是十分必要的。本文中我将介绍一些让bash脚本变得健壮的技术。</p> <h1>使用set -u</h1> <p>你因为没有对变量初始化而使脚本崩溃过多少次？对于我来说，很多次。</p><pre lang-bsh"="">chroot=$1 ... rm -rf $chroot/usr/share/doc</pre> <p>如果上面的代码你没有给参数就运行，你不会仅仅删除掉chroot中的文档，而是将系统的所有文档都删除。那你应该做些什么呢？好在bash提供了<em>set -u</em>，当你使用未初始化的变量时，让bash自动退出。你也可以使用可读性更强一点的<em>set -o nounset</em>。</p> <p><span style="color: #0000ff; font-family: courier new,courier">david% bash /tmp/shrink-chroot.sh </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">$chroot= </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">david% bash -u /tmp/shrink-chroot.sh </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">/tmp/shrink-chroot.sh: line 3: $1: unbound variable </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">david% </span></p> <h1>使用set -e</h1> <p>你写的每一个脚本的开始都应该包含<em>set -e</em>。这告诉bash一但有任何一个语句返回非真的值，则退出bash。使用-e的好处是避免错误滚雪球般的变成严重错误，能尽早的捕获错误。更加可读的版本：<em>set -o errexit</em></p> <p>使用-e把你从检查错误中解放出来。如果你忘记了检查，bash会替你做这件事。不过你也没有办法使用<em>$?</em>来获取命令执行状态了，因为bash无法获得任何非0的返回值。你可以使用另一种结构：</p> <p>command</p> <p><span style="color: #0000ff; font-family: courier new,courier">if [ "$?"-ne 0]; then echo "command failed"; exit 1; fi </span></p> <p>可以替换成：</p> <p><span style="color: #0000ff; font-family: courier new,courier">command || { echo "command failed"; exit 1; } </span></p> <p>或者使用：</p> <p><span style="color: #0000ff; font-family: courier new,courier">if ! command; then echo "command failed"; exit 1; fi </span></p> <p>如果你必须使用返回非0值的命令，或者你对返回值并不感兴趣呢？你可以使用 <em>command || true</em> ，或者你有一段很长的代码，你可以暂时关闭错误检查功能，不过我建议你谨慎使用。</p> <p><span style="color: #0000ff; font-family: courier new,courier">set +e </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">command1 </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">command2 </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">set -e </span></p> <p>相关文档指出，bash默认返回管道中最后一个命令的值，也许是你不想要的那个。比如执行 <em>false | true</em> 将会被认为命令成功执行。如果你想让这样的命令被认为是执行失败，可以使用 <em>set -o pipefail</em></p> <h1>程序防御 - 考虑意料之外的事</h1> <p>你的脚本也许会被放到&#8220;意外&#8221;的账户下运行，像缺少文件或者目录没有被创建等情况。你可以做一些预防这些错误事情。比如，当你创建一个目录后，如果父目录不存在，<strong>mkdir</strong> 命令会返回一个错误。如果你创建目录时给<strong>mkdir</strong>命令加上-p选项，它会在创建需要的目录前，把需要的父目录创建出来。另一个例子是 <strong>rm</strong> 命令。如果你要删除一个不存在的文件，它会&#8220;吐槽&#8221;并且你的脚本会停止工作。（因为你使用了-e选项，对吧？）你可以使用-f选项来解决这个问题，在文件不存在的时候让脚本继续工作。&nbsp;</p> <h1>准备好处理文件名中的空格</h1> <p>有些人从在文件名或者命令行参数中使用空格，你需要在编写脚本时时刻记得这件事。你需要时刻记得用引号包围变量。</p> <p><span style="color: #0000ff; font-family: courier new,courier">if [ $filename = "foo" ]; </span></p> <p>当<em>$filename</em>变量包含空格时就会挂掉。可以这样解决：</p> <p><span style="color: #0000ff; font-family: courier new,courier">if [ "$filename" = "foo" ]; </span></p> <p>使用<em>$@</em>变量时，你也需要使用引号，因为空格隔开的两个参数会被解释成两个独立的部分。</p> <p><span style="color: #0000ff; font-family: courier new,courier">david% foo() { for i in $@; do echo $i; done }; foo bar "baz quux" </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">bar </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">baz </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">quux </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">david% foo() { for i in "$@"; do echo $i; done }; foo bar "baz quux" </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">bar </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">baz quux </span></p> <p>我没有想到任何不能使用<em>"$@"</em>的时候，所以当你有疑问的时候，使用引号就没有错误。</p> <p>如果你同时使用find和xargs，你应该使用 -print0 来让字符分割文件名，而不是换行符分割。</p> <p>&nbsp;<span style="color: #0000ff; font-family: courier new,courier">david% touch "foo bar" </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">david% find | xargs ls </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">ls: ./foo: No such file or directory </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">ls: bar: No such file or directory </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">david% find -print0 | xargs -0 ls </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">./foo bar </span></p> <h1>设置的陷阱</h1> <p>当你编写的脚本挂掉后，文件系统处于未知状态。比如锁文件状态、临时文件状态或者更新了一个文件后在更新下一个文件前挂掉。如果你能解决这些问题， 无论是  删除锁文件，又或者在脚本遇到问题时回滚到已知状态，你都是非常棒的。幸运的是，bash提供了一种方法，当bash接收到一个UNIX信号时，运行一个  命令或者一个函数。可以使用<strong>trap</strong>命令。</p> <p><span style="color: #0000ff; font-family: courier new,courier">trap command signal [signal ...] </span></p> <p>你可以链接多个信号（列表可以使用kill -l获得），但是为了清理残局，我们只使用其中的三个：<em>INT</em>，<em>TERM</em>和<em>EXIT</em>。你可以使用-as来让traps恢复到初始状态。</p> <h4>信号描述</h4> <p>&nbsp;</p> <table style="width: 100%" align="left" border="0" cellpadding="2" cellspacing="0"> <tbody> <tr> <td>INT</td> <td> <p>Interrupt - 当有人使用Ctrl-C终止脚本时被触发</p></td></tr> <tr> <td>TERM</td> <td> <p>Terminate - 当有人使用kill杀死脚本进程时被触发</p></td></tr> <tr> <td>EXIT</td> <td> <p>Exit - 这是一个伪信号，当脚本正常退出或者set -e后因为出错而退出时被触发</p></td></tr></tbody></table> <p>&nbsp;</p> <p>&nbsp;</p> <p>&nbsp;</p> <p>&nbsp;</p> <p>当你使用锁文件时，可以这样写：</p> <p><span style="color: #0000ff; font-family: courier new,courier">if [ ! -e $lockfile ]; then </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">touch $lockfile </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">critical-section </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">rm $lockfile </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">else </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">echo "critical-section is already running" </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">fi </span></p> <p>当最重要的部分(critical-section)正在运行时，如果杀死了脚本进程，会发生什么呢？锁文件会被扔在那，而且你的脚本在它被删除以前再也不会运行了。解决方法：</p> <p><span style="color: #0000ff; font-family: courier new,courier">if [ ! -e $lockfile ]; then </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">trap " rm -f $lockfile; exit" INT TERM EXIT </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">touch $lockfile </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">critical-section </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">rm $lockfile </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">trap - INT TERM EXIT </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">else </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">echo "critical-section is already running" </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">fi </span></p> <p>现在当你杀死进程时，锁文件一同被删除。注意在trap命令中明确地退出了脚本，否则脚本会继续执行trap后面的命令。</p> <h1>竟态条件 (<a href="http://zh.wikipedia.org/wiki/%E7%AB%B6%E7%88%AD%E5%8D%B1%E5%AE%B3" target="_blank">wikipedia</a>)</h1> <p>在上面锁文件的例子中，有一个竟态条件是不得不指出的，它存在于判断锁文件和创建锁文件之间。一个可行的解决方法是使用IO重定向和bash的noclobber(<a href="http://en.wikipedia.org/wiki/Clobbering" target="_blank">wikipedia</a>)模式，重定向到不存在的文件。我们可以这么做：</p> <p><span style="color: #0000ff; font-family: courier new,courier">if ( set -o noclobber; echo "$$" &gt; "$lockfile") 2&gt; /dev/null; </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">then </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">critical-section </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">rm -f "$lockfile" </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">trap - INT TERM EXIT </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">else </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">echo "Failed to acquire lockfile: $lockfile" </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">echo "held by $(cat $lockfile)" </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">fi </span></p> <p>更复杂一点儿的问题是你要更新一大堆文件，当它们更新过程中出现问题时，你是否能让脚本挂得更加优雅一些。你想确认那些正确更新了，哪些根本没有变化。比如你需要一个添加用户的脚本。</p> <p><span style="color: #0000ff; font-family: courier new,courier">add_to_passwd $user </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">cp -a /etc/skel /home/$user </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">chown $user /home/$user -R </span></p> <p>当磁盘空间不足或者进程中途被杀死，这个脚本就会出现问题。在这种情况下，你也许希望用户账户不存在，而且他的文件也应该被删除。</p> <p><span style="color: #0000ff; font-family: courier new,courier">rollback() { </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">del_from_passwd $user </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">if [ -e /home/$user ]; then </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">rm -rf /home/$user </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">fi </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">exit </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">} </span></p> <p>&nbsp;</p> <p><span style="color: #0000ff; font-family: courier new,courier">trap rollback INT TERM EXIT </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">add_to_passwd $user </span></p> <p>&nbsp;</p> <p><span style="color: #0000ff; font-family: courier new,courier">cp -a /etc/skel /home/$user </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">chown $user /home/$user -R </span></p>  <p><span style="color: #0000ff; font-family: courier new,courier">trap - INT TERM EXIT </span></p> <p>在脚本最后需要使用trap关闭rollback调用，否则当脚本正常退出的时候rollback将会被调用，那么脚本等于什么都没做。</p> <h1>保持原子化</h1> <p>又是你需要一次更新目录中的一大堆文件，比如你需要将URL重写到另一个网站的域名。你也许会写：</p> <p><span style="color: #0000ff; font-family: courier new,courier">for file in $(find /var/www -type f -name "*.html"); do </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">perl -pi -e 's/www.example.net/www.example.com/' $file </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">done </span></p> <p>如果修改到一半是脚本出现问题，一部分使用www.example.com，而另一部分使用www.example.net。你可以使用备份和trap解决，但在升级过程中你的网站URL是不一致的。</p> <p>解决方法是将这个改变做成一个原子操作。先对数据做一个副本，在副本中更新URL，再用副本替换掉现在工作的版本。你需要确认副本和工作版本目录在同一个磁盘分区上，这样你就可以利用Linux系统的优势，它移动目录仅仅是更新目录指向的inode节点。</p> <p><span style="color: #0000ff; font-family: courier new,courier">cp -a /var/www /var/www-tmp </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">for file in $(find /var/www-tmp -type -f -name "*.html"); do </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">perl -pi -e 's/www.example.net/www.example.com/' $file </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">done </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">mv /var/www /var/www-old </span></p> <p><span style="color: #0000ff; font-family: courier new,courier">mv /var/www-tmp /var/www </span></p> <p>这意味着如果更新过程出问题，线上系统不会受影响。线上系统受影响的时间降低为两次mv操作的时间，这个时间非常短，因为文件系统仅更新inode而不用真正的复制所有的数据。</p> <p>这种技术的缺点是你需要两倍的磁盘空间，而且那些长时间打开文件的进程需要比较长的时间才能升级到新文件版本，建议更新完成后重新启动这些进程。对 于  apache服务器来说这不是问题，因为它每次都重新打开文件。你可以使用lsof命令查看当前正打开的文件。优势是你有了一个先前的备份，当你需要还原  时，它就派上用场了。</p></div>转自: http://www.linuxidc.com/Linux/2012-03/56614.htm<img src ="http://www.cppblog.com/guojingjia2006/aggbug/197146.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2013-01-09 12:11 <a href="http://www.cppblog.com/guojingjia2006/archive/2013/01/09/197146.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux上文件的特殊权限SUID,SGID,SBIT详解</title><link>http://www.cppblog.com/guojingjia2006/archive/2013/01/07/197084.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Mon, 07 Jan 2013 11:51:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2013/01/07/197084.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/197084.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2013/01/07/197084.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/197084.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/197084.html</trackback:ping><description><![CDATA[<div><p>文件的特殊权限SGID, SUID..SBIT</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  大家都知道文件和目录的权限最常见的有三个.可读(r)..可写(w)..可执行(x)..它们的级别分别是4..2..1..我们有时也会发现有些文件 所属主的权限上带有一个s的标志位.目录的所属组上也带有s标志位.很多人不理解这是为什么....下面我们举例来看一下...<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #ls -l&nbsp; /usr/bin/passwd<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -rwsr-xr-x 1 root root 19876 Jul 17&nbsp; 2006 /usr/bin/passwd<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个文件的所属主的x标志位上变成了s,这时称为set uid ..简写就是suid..其实这个文件属性也没有特殊的含义..当这个s标志位出现在一些脚本上时,它就有意义了...比方说我我们有一个脚本名为sum.sh.这个脚本的权限如下:<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -rwsrwxr-x 1 root root&nbsp;&nbsp; 117 Feb&nbsp; 6 20:46 sum.sh<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  这个脚本的所属主和所属组为root.我们当然可以以root的用户的身份执行它..我们还可以看见它的所属主的标志位上有个s..其他人有读取和执行的 权限.假如我们现在有个普通用户名为redhat..现在切换到redhat..执行此脚本..表面上我们看是执行成功了..其实我们是借助root用户 的身份来执行它..而不是redhat..这就是suid的特性....<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下满我们来说下SGID,看了上面的SUID后很容易就知道所谓SGID就是将标志s加到gid的x标志位上..称为set  gid.简称sgid..在这强调一下SUID我们一般用在文件上.特别是一些脚本上...SGID用在目录上最多...比方说我以root身份创建一个 目录a.给他加上sgid权限<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #mkdir a <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #chmod&nbsp;&nbsp; 2757&nbsp; a <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #ls&nbsp; -l <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drwxr-srwx 2 root root&nbsp; 4096 Feb&nbsp; 6 21:09&nbsp; a<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 因为我们给a目录其他人所具有的权限是可读,可写,可执行...当我们以redhat用户的身份切换到另外一个终端..进入a目录中,我们在此目录中创建一个目录b和一个文件c<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [redhat@station18 a]$ mkdir b<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [redhat@station18 a]$ touch c<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [redhat@station18 a]$ ls -l<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drwxrwsr-x 2 redhat root 4096 Feb&nbsp; 6 21:20 b<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -rw-rw-r-- 1&nbsp;&nbsp;&nbsp; redhat root&nbsp;&nbsp;&nbsp; 0 Feb&nbsp; 6 21:20 c <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  我们可以看到目录b和文件c的所属组都为root......当你将一个a目录置为sgid权限时候,如果其他人有读取,执行和写入的权限时,别人在此目 录中创建的任何文件和目录的所属组都为a目录的所属组..但所属主还是自己...这个会经常的用到....有一点大家得注意...就是任何人在a目录中创 建的东西.别人都可以删掉...这就是我们下面要讲到的SBIT....<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SBIT 全称Sticky Bit.但是它只对目录有效,对文件却是无效的,它的作用就是防止别人删除对方的资料...我们举例来说明...<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1..我用root用户登录创建一个目录名为test<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [root@station18 ~]# mkdir test<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [root@station18 ~]# chmod o+w test/<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [root@station18 ~]# ls -l <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drwxr-xrwx 2 root root&nbsp; 4096 Feb&nbsp; 6 21:30 test<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2..我们切换到redhat用户登录一个终端,创建一个目录a..<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [redhat@station18 test]$ mkdir a<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.我们在切换到xiaoming用户登录一个终端,创建一个目录b...<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [xiaoming@station18 test]$ mkdir b<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [xiaoming@station18 test]$ ls&nbsp; -l<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drwxrwxr-x 2 redhat&nbsp;&nbsp; redhat&nbsp;&nbsp; 4096 Feb&nbsp; 6 21:32 a<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drwxrwxr-x 2 xiaoming xiaoming 4096 Feb&nbsp; 6 21:31 b<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我们可以以任何用户的身份进入test目录发现可以删除a和b目录...这样就乱了套...别人的目录你岂能随便删的...这时我们就需要将test目录加上SBIT权限了...<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [root@station18 ~]# chmod&nbsp; 1757&nbsp; test/<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [root@station18 ~]# ls -l<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drwxr-xrwt 4 root root&nbsp; 4096 Feb&nbsp; 6 21:42 test<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我们在用别的用户登录进入test目录他就删不掉别人的资料了,系统会提示rm: cannot remove directory  `a': Operation not permitted..意思是你权限不够....呵呵...这样别人就没辙了....我测试过成功的... <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面我来说一下关于SUID SGID&nbsp; SBIT权限的设定...<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SUID为4<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SGID为2<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SBIT为1<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我在上面设定一些文件或目录的权限你可能看不懂,,下面我来详细讲解...<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 假如我们有个文件叫file.有一个目录叫test..file它的权限是644..test的权限是755<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1..如果我们想把file加上suid权限的话执行此命令<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #chmod&nbsp; 4755&nbsp; file<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2..如果我们想把test目录加上sgid的话执行此命令<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #chmod&nbsp; 2755&nbsp;&nbsp; test/<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.如果我们想把test目录加上sbit权限的话执行此命令<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #chmod&nbsp; 1755&nbsp;&nbsp; test/<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4..大家可以看得出来s与t都是取代x权限的...<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5..如果不想让test具备SUID和SGID权限执行此命令<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #chmod&nbsp;&nbsp; 7666&nbsp; file<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #ls&nbsp; -l<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -rwSrwSrwT 1 root root&nbsp;&nbsp;&nbsp;&nbsp; 0 Feb&nbsp; 6 21:49 file<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这里的S和T就代表空..不具备其他人执行的权限...7666也就是说用户,组,以及其他的人都不具备x的权限,除了root.任何人修改不了此文件...<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这儿我用数字代替给文件加一些 权限....我们也可以用别的方法.比方说..我们给file文件加上suid权限<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #chmod&nbsp; u=rwxs,o=rx&nbsp;&nbsp; file<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 给test目录加上SGID权限和other可读取写入执行权限<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #chmod&nbsp; g+s,o=wrx&nbsp;&nbsp;&nbsp; test/<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 给test目录加上SBIT权限和other可读取写入执行权限<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #chmod&nbsp;&nbsp; o=rwxt&nbsp;&nbsp; test/ <br />&nbsp;<div>原文：<a href="http://blog.chinaunix.net/u3/111913/showart_2182986.html" rel="nofollow" target="_blank">http://blog.chinaunix.net/u3/111913/showart_2182986.html</a></div><br /></p></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/197084.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2013-01-07 19:51 <a href="http://www.cppblog.com/guojingjia2006/archive/2013/01/07/197084.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>centos 上安装gearman</title><link>http://www.cppblog.com/guojingjia2006/archive/2013/01/07/197076.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Mon, 07 Jan 2013 08:39:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2013/01/07/197076.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/197076.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2013/01/07/197076.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/197076.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/197076.html</trackback:ping><description><![CDATA[<div><div>官网：http://gearman.org/</div><br />跨多种环境部署 Gearman<br /> http://www.ibm.com/developerworks/cn/opensource/os-gearman/index.html<br /> 利用开源的Gearman框架构建分布式图片处理平台－张宴<br /> http://blog.s135.com/dips/<br /> 监控：<br /> https://github.com/yugene/Gearman-Monitor <br /> <br /> 一、简介<br /> Gearman是一个分发任务的程序架构，由三部分组成：<br /> Gearman client：提供gearman client API给应用程序调用。API可以使用C,PHP,PERL,MYSQL UDF等待呢个语言，它是请求的发起者。<br /> Gearman job server：将客户端的请求分发到各个gearman worker的调度者，相当于中央控制器，但它不处理具体业务逻辑。<br /> Gearman worker：提供gearman worker API给应用程序调用，具体负责客户端的请求，并将处理结果返回给客户端。<br /> Mogilefs的分布式文件系统的核心就是用gearman实现的。<br /> 这个软件的应用场景很多，比如视频网站的视频处理，分布式日志处理，电子邮件处理，文件同步处理，图片处理等等，只要是可以放开，不影响体验和响应的场 景，需要并行进行大量计算和处理的程序都是可以的。Yahoo在60或更多的服务器上使用gearman每天处理600万个作业。新闻聚合器digg构建 了一个相同规模的gearman网络，每天可处理400000个作业。<br /> Gearman不但可以做为任务分发，还可以做为应用方面的负载均衡。可以让worker放在不同的一堆服务器上，也可以启动放在同一个cpu的多个核 上。比如，应用视频转换程序，不希望web服务器来处理视频格式转换，这时，可以在这一堆服务器上进行任务分发，在上面加载worker处理视频格式，对 外的web服务器就不会被视频转换过程影响。而且扩展方便，加一台服务器到任务调度中心，注册成worker即可，这时job  server会在请求到来的时候，将请求发送给空闲的worker。还可以运行多个job server，组成ha架构，如果一个job  server当掉了，client和worker会自动迁移到另一台job server上。<br /> <br /> 二、安装<br /> [Job Server (gearmand) -- 172.16.1.183]<br /> 1.首先安装libdrizzle<br /> &nbsp;&nbsp;&nbsp; #yum install libdrizzle libdrizzle-devel<br /> 2.安装gearman（两种方法1.yum2.源码包）。（c版的server）<br /> &nbsp;&nbsp;&nbsp; 1）yum安装<br /> &nbsp;&nbsp;&nbsp; #rpm -ivh http://dl.iuscommunity.org/pub/ius/stable/Redhat/6/x86_64/epel-release-6-5.noarch.rpm<br /> &nbsp;&nbsp;&nbsp; #yum install -y gearmand<br /> &nbsp;&nbsp;&nbsp; 2）源码包安装<br /> &nbsp;&nbsp;&nbsp; #cd /opt/build/<br /> &nbsp;&nbsp;&nbsp; #wget https://launchpad.net/gearmand/trunk/0.34/+download/gearmand-0.34.tar.gz<br /> &nbsp;&nbsp;&nbsp; #tar zxf gearmand-0.34.tar.gz<br /> &nbsp;&nbsp;&nbsp; #cd gearmand-0.34<br /> &nbsp;&nbsp;&nbsp; #./configure<br /> &nbsp;&nbsp;&nbsp; #make &amp;&amp; make install<br /> 3.启动gearman服务<br /> &nbsp;&nbsp;&nbsp; 1）yum安装方式<br /> &nbsp;&nbsp;&nbsp; #/etc/init.d/gearmand start<br /> &nbsp;&nbsp;&nbsp; 2）源码包安装方式<br /> &nbsp;&nbsp;&nbsp; #/opt/build/gearmand-0.34/sbin/gearmand -d<br /> <br /> &nbsp;&nbsp;&nbsp; #gearmand -vvv -u root <br /> &nbsp;&nbsp;&nbsp; INFO Starting up<br /> &nbsp;&nbsp;&nbsp; INFO Listening on :::4730 (6)<br /> &nbsp;&nbsp;&nbsp; INFO Creating wakeup pipe<br /> &nbsp;&nbsp;&nbsp; INFO Creating IO thread wakeup pipe<br /> &nbsp;&nbsp;&nbsp; INFO Adding event for listening socket (6)<br /> &nbsp;&nbsp;&nbsp; INFO Adding event for wakeup pipe<br /> &nbsp;&nbsp;&nbsp; INFO Entering main event loop<br /> <br /> worker&amp;&amp;client以php方式<br /> [worker --&nbsp; 172.16.1.180]<br /> 安装gearmand如上所示<br /> <br /> 安装 Gearman PHP extension<br /> 1.下载gearman-0.8.0.tgz并安装<br /> &nbsp;&nbsp;&nbsp; #cd /opt/build/<br /> &nbsp;&nbsp;&nbsp; #wget http://pecl.php.net/get/gearman-0.8.0.tgz<br /> &nbsp;&nbsp;&nbsp; # yum install -y libgearman-devel.x86_64<br /> &nbsp;&nbsp;&nbsp; # yum install -y re2c <br /> &nbsp;&nbsp;&nbsp; #tar zxf gearman-0.8.0.tgz <br /> &nbsp;&nbsp;&nbsp; #cd gearman-0.8.0.tgz<br /> &nbsp;&nbsp;&nbsp; #phpize<br /> &nbsp;&nbsp;&nbsp; # ./configure<br /> &nbsp;&nbsp;&nbsp; # make &amp;&amp; make install<br /> 2.编辑php.ini配置文件加载相应模块并使之生效<br /> &nbsp;&nbsp;&nbsp; # vim /etc/php.ini<br /> &nbsp;&nbsp;&nbsp; extension = "gearman.so"<br /> 3.查看gearman.so模块是否加载<br /> &nbsp;&nbsp;&nbsp; # php --info | grep gearman<br /> &nbsp;&nbsp;&nbsp; gearman<br /> &nbsp;&nbsp;&nbsp; gearman support =&gt; enabled<br /> &nbsp;&nbsp;&nbsp; libgearman version =&gt; 0.14<br /> &nbsp;&nbsp;&nbsp; PWD =&gt; /opt/build/gearman-0.8.0<br /> &nbsp;&nbsp;&nbsp; _SERVER["PWD"] =&gt; /opt/build/gearman-0.8.0<br /> &nbsp;&nbsp;&nbsp; # php -m | grep gearman<br /> &nbsp;&nbsp;&nbsp; gearman<br /> 4.启动job<br /> gearmand -d<br /> 如果当前用户是 root 的话，则需要这样操作：<br /> gearmand -d -u root<br /> 缺省会使用 4730 端口，下面会用到。<br /> &nbsp;&nbsp;&nbsp; 注意：如果找不到 gearmand 命令的路径，别忘了用 whereis gearmand 确认<br /> <br /> [client -- 172.16.1.181]<br /> &nbsp;&nbsp;&nbsp; 安装如work同。如上所示。<br /> <br /> 三、测试：<br /> [Job Server (gearmand) -- 172.16.1.183]<br /> 启动gearmand<br /> <br /> 以命令行工具来验证gearman的功能<br /> 启动 Worker：gearman -h 172.16.1.183 -w -f wc -- wc -l &amp;<br /> 运行Client：gearman -h 172.16.1.183 -f wc &lt; /etc/passwd<br /> 42<br /> 可以看到验证成功。<br /> <br /> 以php验证gearman的功能<br /> 编写 Worker<br /> worker.php 文件内容如下：<br /> &lt;?php<br /> $worker= new GearmanWorker();<br /> $worker-&gt;addServer('172.16.1.183', 4730);<br /> $worker-&gt;addFunction('reverse', 'my_reverse_function');<br /> while ($worker-&gt;work());<br /> function my_reverse_function($job) {<br /> return strrev($job-&gt;workload());<br /> }<br /> ?&gt;<br /> 设置后台运行 work<br /> php worker.php &amp;<br /> 编写 Client<br /> client.php 文件内容如下：<br /> &lt;?php<br /> $client= new GearmanClient();<br /> $client-&gt;addServer('172.16.1.183', 4730);<br /> echo $client-&gt;do('reverse', 'Hello World!'), "\n";<br /> ?&gt;<br /> 运行 client<br /> php client.php<br /> 输出：!dlroW olleH<br /><br />Q:<br /><div><div itemprop="description">         <p>I've been trying to get Gearman compiled on CentOS 5.8 all  afternoon. Unfortunately I am restricted to this version of CentOS by my  CTO and how he has our entire network configured. I think it's simply  because we don't have enough resources to upgrade our network... But  anyways, the problem at hand.</p>  <p>I have searched through Server Fault, Stack Overflow, Google, and am  unable to locate a working solution. What I have below is stuff I have  pieced together from my searching.</p>  <p>Searches have told said to install the following via <code>yum</code>:</p>  <pre><code>yum -y install --enablerepo=remi boost141-devel libgearman-devel e2fsprogs-devel e2fsprogs gcc44 gcc-c++ </code></pre>  <p>To get the Boost headers working correctly I did this:</p>  <pre>cp -f /usr/lib/boost141/* /usr/lib/ cp -f /usr/lib64/boost141/* /usr/lib64/ rm -f /usr/include/boost ln -s /usr/include/boost141/boost /usr/include/boost </pre>  <p>With all of the dependancies installed and paths setup I then download and compile <code>gearmand-1.1.2</code> just fine.</p>  <pre>wget -O /tmp/gearmand-1.1.2.tar.gz https://launchpad.net/gearmand/1.2/1.1.2/+download/gearmand-1.1.2.tar.gz cd /tmp &amp;&amp; tar zxvf gearmand-1.1.2.tar.gz ./configure &amp;&amp; make -j8 &amp;&amp; make install </pre>  <p>That works correctly. So now I need to install the Gearman library  for PHP. I have attempted through PECL and downloading the source  directly, both result in the same error:</p>  <pre>checking whether to enable gearman support... yes, shared not found configure: error: Please install libgearman </pre>  <p>What I don't understand is I installed the <code>libgearman-devel</code> package which also installed the core <code>libgearman</code>. The installation installs <code>libgearman-devel-0.14-3.el5.x86_64</code>, <code>libgearman-devel-0.14-3.el5.i386</code>, <code>libgearman-0.14-3.el5.x86_64</code>, and <code>libgearman-0.14-3.el5.i386</code>.</p>  <p>Is it possible the package version is lower than what is required?  I'm still poking around with this, but figured I'd throw this up to see  if anyone has a solution while I continue to research a fix.</p>  <p>Thanks!</p>      </div></div><br />A:<br /><div><div><p>This should do the trick:</p>  <pre><code>export GEARMAN_LIB_DIR=/usr/include/libgearman <br />export GEARMAN_INC_DIR=/usr/include/libgearman </code></pre>  <p>That should work, if not you'll have to do some minor edits to config.m4.</p><p><br /></p><p>other:</p><p><div>http://gearman.org/gearman_php_extension</div><div>http://blog.csdn.net/aidenliu/article/details/7406390</div><div>http://www.php.net/manual/en/gearmanclient.dobackground.php</div><div>http://www.wenzizone.com/2012/09/27/how_to_fix_rpm_filedigests_payloadisxz_is_needed.html</div><div>http://www.2cto.com/os/201206/136785.html</div><div>http://blog.s135.com/dips</div><div>http://blog.csdn.net/hfahe/article/details/5519582</div><div>http://hi.baidu.com/sunjiujiu/item/4406281c952cf47a7b5f2594</div><br /></p> </div></div><div></div></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/197076.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2013-01-07 16:39 <a href="http://www.cppblog.com/guojingjia2006/archive/2013/01/07/197076.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mint 下codeblocks 编译libapue </title><link>http://www.cppblog.com/guojingjia2006/archive/2013/01/04/196955.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Fri, 04 Jan 2013 12:23:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2013/01/04/196955.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/196955.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2013/01/04/196955.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/196955.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/196955.html</trackback:ping><description><![CDATA[codeblocks很轻巧也很好用对于c/c++编写在linux下相对于eclipse.<br />于是乎下了一个，由于是乎想写几个sample玩玩。于是乎拿&lt;unix 高级环境编程&gt; sample来测试。<br /><br />于是乎建了一个c++ project. <div>&lt;unix 高级环境编程&gt;里的例子有个apue.h头文件。不是系统自带的。是作者自己写的几个util函数。<br />网上找编译apue.h头文件一大片。但是都是考来考去，不过核心的都差不多。不过有个方法是编译完<br />libapue.a静态库后，还需要在apute.h头文件尾巴加"error.c"。。完了拷贝error.c实现到目录。。<br />看完后。我惊了呆。。好吧。。这库还能这么用。。<br /><br />既然libapue.a编译完后，apue.h里的函数声明在libapue.a都已经实现，当然包括err_xxx系列的。所以<br />在apue.h加"error.c"是画蛇添足。。这里不推荐此方法。。<br /><br />我的环境是mint14下, IDE用的是 codeblocks. 方法中基本都有这么一个步骤：<br /><div> <div>先在这个网站&nbsp;http://www.apuebook.com/src.tar.gz  下载tar.gz格式的源码包，然后解压至某个目录，比如说/home/xiaoguozi/下，然后进入目录apue.2e，把文件  Make.defines.linux 中的 WKDIR=/home/xxx/apue.2e 修改为  WKDIR=/home/xiaoguozi/apue.2e  ，然后再进入apue.2e目录下的std目录，打开linux.mk，将里面的nawk全部替换为awk</div></div>如果用vim编辑的话，可以用 :1,%s/nawk/awk/g 替换字符窜<br /><br />完了make, 过程中，还遇到了几个问题。(mint下,其他os不太清楚)<br /><div><p><span style="font-size:18px">1: /usr/include/bits/timex.h:31:7:error: expect ':' , ',' , ';' , '}' or '__attribute__'&nbsp; &nbsp; <br /></span><span style="font-size:18px">&nbsp;apue.2e/ipp/ipp.h中 #define status u.st 与 timex.h中的 status 冲突，更改 #define Status u.st</span></p> <p><span style="font-family:Arial; line-height:26px"><span style="font-size:14px">&nbsp;&nbsp;</span></span></p> <p><span style="font-family:Arial; line-height:26px"><span style="font-size:14px"><span style="margin:0px; padding:0px; border:none; font-family:Consolas,'Courier New',Courier,mono,serif; line-height:17.600000381469727px">2：ARG_MAX 未定义</span></span></span></p> <p><span style="font-family:Consolas,Courier New,Courier,mono,serif; font-size:14px"><span style="line-height:17.600000381469727px">&nbsp; &nbsp;在include/apue.h中加入 #define ARG_MAX 4096</span></span></p> <p><span style="font-family:Consolas,Courier New,Courier,mono,serif; font-size:14px"><span style="line-height:17.600000381469727px">&nbsp; &nbsp;在threadctl/getenv1.c 加入 #include "../include/apue.h"</span></span></p> <p><span style="font-family:Consolas,Courier New,Courier,mono,serif; font-size:14px"><span style="line-height:17.600000381469727px">&nbsp; &nbsp;在threadctl/getenv3.c 加入 #include "../include/apue.h"</span></span></p></div>完了之后，make应该就可以成功了<br /><br />完了在codeblocks项目里引用刚编译完的库，有几个方法:<br />1)将编译完的库,头文件apue.h拷贝/usr/include,库文件libapue.a拷贝到/usr/lib下，这个是系统目录，gcc编译的时候会在这目录搜寻<br />2)在项目属性添加静态库引用<br /><div>添加头文件：依次点击project-&gt;bulid options-&gt;Search directories，在该标签页中点击Compiler，单击Add按钮添加头文件路径<br />添加静态库路径：依次点击project-&gt;bulid options-&gt;Linker setting，在该标签页中点击Add按钮添加静态库路径。<br /><br />如果之前你建的是c project的话，应该就可以顺利编译通过了，但是对于建立c++的project,仍然提示链接错误，找不到函数实现，<br />原因是libapue.a是c库，用g++编译的时候要引用c库的话，因为c++编译的时候会在函数加一些额外字符，所以当然会链接错误。</div><div>解决也简单的在函数库前加 extern "C",或者直接把apue.h用extern "C"包含，不清楚的补下相应知识。<br /><br />加点额外的知识关于gcc/g++：<br /><div>gcc和g++的区别<p>误区一:gcc只能编译c代码,g++只能编译c++代码<br />两者都可以，但是请注意：<br />1.后缀为.c的，gcc把它当作是C程序，而g++当作是c++程序；后缀为.cpp的，两者都会认为是c++程序，注意，虽然c++是c的超集，但是两者对语法的要求是有区别的。C++的语法规则更加严谨一些。<br />2.编译阶段，g++会调用gcc，对于c++代码，两者是等价的，但是因为gcc命令不能自动和C＋＋程序使用的库联接，所以通常用g++来完成链接，为了统一起见，干脆编译/链接统统用g++了，这就给人一种错觉，好像cpp程序只能用g++似的。<br /><br />误区二:gcc不会定义__cplusplus宏，而g++会<br />实际上，这个宏只是标志着编译器将会把代码按C还是C++语法来解释，如上所述，如果后缀为.c，并且采用gcc编译器，则该宏就是未定义的，否则，就是已定义。<br /><br />误区三:编译只能用gcc，链接只能用g++<br />严格来说，这句话不算错误，但是它混淆了概念，应该这样说：编译可以用gcc/g++，而链接可以用g++或者gcc -lstdc++。因为gcc命令不能自动和C＋＋程序使用的库联接，所以通常使用g++来完成联接。但在编译阶段，g++会自动调用gcc，二者等价。</p>                                                                                                                          gcc和g++的区别                                                                                                                                                                                                                                                                                                                                                                       我们在编译c/c++代码的时候，有人用gcc，有人用g++，于是各种说法都来了，譬如c代码用gcc，而c++代码用g++，或者说编译用  gcc，链接用g++，一时也不知哪个说法正确，如果再遇上个extern  "C"，分歧就更多了，这里我想作个了结，毕竟知识的目的是令人更清醒，而不是更糊涂。</div></div><br /></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/196955.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2013-01-04 20:23 <a href="http://www.cppblog.com/guojingjia2006/archive/2013/01/04/196955.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>raid 相关</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/12/13/196219.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Thu, 13 Dec 2012 09:13:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/12/13/196219.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/196219.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/12/13/196219.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/196219.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/196219.html</trackback:ping><description><![CDATA[<div>http://wenku.baidu.com/view/195a16eae009581b6bd9eb1b.html</div><div>http://blog.chinaunix.net/uid-20344928-id-3195698.html</div><div>http://www.issacy.com/archives/770.html</div><div>http://www.cnblogs.com/linuxer/archive/2012/03/07/2441224.html</div><div>http://zhidao.baidu.com/question/266486719.html</div><div>http://blog.163.com/fxd_3/blog/static/59261582201211032530668/</div><div><div>http://storage.chinaunix.net/stor/raid/2008/05/28/1117871.shtml</div><div>http://www.ibmsos.cn/a/IBMfuwuqijishuzhuanti/IBMfuwuqiyingjian_ruanjian/2011/0720/127.html</div><div>http://qijianghao.blog.51cto.com/3258446/787961</div><div>http://www.jb51.net/article/30494.htm</div></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/196219.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-12-13 17:13 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/12/13/196219.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux 账号管理及密码过期设置</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/12/06/196050.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Thu, 06 Dec 2012 11:22:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/12/06/196050.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/196050.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/12/06/196050.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/196050.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/196050.html</trackback:ping><description><![CDATA[<div><p><div>Linux下对于新添加的用户，用户密码过期时间是从/etc/login.defs中PASS_MAX_DAYS提取的，普通系统默认就是99999，而有些安全操作系统是90。更改此处，只是让新建的用户默认密码过期时间变化，已有用户密码过期时间仍然不变。</div><br /></p><p>[root@linuxidc ~]# chage --help<br />Usage: chage [options] user</p> <p>Options:<br />&nbsp;<wbr> -d, --lastday LAST_DAY&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> set last password change to LAST_DAY<br />&nbsp;<wbr> -E, --expiredate EXPIRE_DATE&nbsp;<wbr> set account expiration date to EXPIRE_DATE<br />&nbsp;<wbr> -h, --help&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> display this help message and exit<br />&nbsp;<wbr> -I, --inactive INACTIVE&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> set password inactive after expiration<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> to INACTIVE<br />&nbsp;<wbr> -l, --list&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> show account aging information<br />&nbsp;<wbr> -m, --mindays MIN_DAYS&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> set minimum number of days before password<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> change to MIN_DAYS<br />&nbsp;<wbr> -M, --maxdays MAX_DAYS&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> set maximim number of days before password<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> change to MAX_DAYS<br />&nbsp;<wbr> -W, --warndays WARN_DAYS&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> set expiration warning days to WARN_DAYS&nbsp;<wbr></p> <p>chage：密码失效是通过此命令来管理的。</p> <p>　　参数意思：<br />　　-m 密码可更改的最小天数。为零时代表任何时候都可以更改密码。<br />　　-M 密码保持有效的最大天数。www.linuxidc.com<br />　　-W 用户密码到期前，提前收到警告信息的天数。<br />　　-E 帐号到期的日期。过了这天，此帐号将不可用。<br />　　-d 上一次更改的日期<br />　　-i 停滞时期。如果一个密码已过期这些天，那么此帐号将不可用。<br />　　-l 例出当前的设置。由非特权用户来确定他们的密码或帐号何时过期。</p> <p>[root@linuxidc ~]# chage -l root<br />Last password change&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> : Oct 19, 2010<br />Password expires&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> : never<br />Password inactive&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> : never<br />Account expires&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> : never<br />Minimum number of days between password change&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> : 0<br />Maximum number of days between password change&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> : 99999<br />Number of days of warning before password expires&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> : 7</p> <p>更改用: chage -M 90 root</p> <p>[root@linuxidc ~]#chage -M 90 root</p> <p>[root@linuxidc ~]#chage -l root<br /></p> <p>如果以后添加一个用户,那么默认的时间还是没改的,还必须得去/etc/login.defs修改PASS_MAX_DAYS  的默认值.那么如果我直接修改全局/etc/login.defs所在的用户会跟着改变吗?  据我的测试是不会改变的,除非重启后,但我们的服务器不是你想重启的就可以重启的!如果管理严格的地方,重启还得经过很多程序步骤.改完全局时,没有更改 的用户,想要让他也同样具备此功能.就得一个个的执行!</p> <p>你也可以直接用vim 编辑器去编辑PASS_MAX_DAYS 99999</p> <p>也可以用其它的工具</p> <p>[root@linuxidc ~]#sed -i.bak -e 's/^\(PASS_MAX_DAYS\).*/\1&nbsp;<wbr>&nbsp;<wbr> 90/' /etc/login.defs</p> <p>查看一下是否</p> <p>[root@linuxidc ~]#cat /etc/login.defs |grep "PASS_M";</p> <p>强制用户登陆时修改口令<br />[root@linuxidc ~]#chage -d 0 username（linux）<br />[root@linuxidc ~]#passwd -f username(solaris)</p> <p>强制用户下次登陆时修改密码，并且设置密码最低有效期0和最高有限期90，提前15天发警报提示<br />[root@linuxidc ~]#chage -d 0 -m 0 -M 90 -W 15 root（linux）<br />[root@linuxidc ~]#passwd -f -n 0 -x 90 -w 15 root（solaris）<br />查看某个用户的密码设置情况<br />[root@linuxidc ~]#chage -l username<br />修改密码配置文件<br />[root@linuxidc ~]#vi /etc/login.defs</p></div><br />//账号<br /><br /><div>Linux ssh建立一个新的用户包括两个步骤，第一步是使用useradd命令完成一个新用户的初始化设置工作;第二步是用passwd为这个新用户设置密码。例如，我们要给系统添加一个用户叫floatboat ，密码为lan2010，那相关的操作是： <p>　　useradd floatboat -d /u01/Lanlp&lt;回车&gt;</p> <p>　　这时候系统没有任何显示。接着：</p> <p>　　passwd floatboat &lt;回车&gt;</p> <p>　　系统显示：</p> <p>　　Changing password for user floatboat</p> <p>　　New UNIX password:</p> <p>　　你输入：</p> <p>　　lan2010&lt;回车&gt;</p> <p>　　注意，由于linux并不采用类似windows的密码回显(显示为*号)&#8212;&#8212;为避免你输入密码时被人注意到有多少位&#8212;&#8212;所以，输入的这些字符你是看不见的。</p> <p>　　系统显示：</p> <p>　　Retype new UNIX password:</p> <p>　　你再重新输入一次密码，然后回车确认，这时系统会显示：</p> <p>　　passwd:all authentication tokens updated successfully</p> <p>　　表示你修改密码成功了。</p> <p>　　到这里，新用户的创建工作就算完成了。</p> <p>　　下面，我们再补充一些有关增加新用户的常识：</p> <p>　　1、useradd所做的初始化操作已经包括在/home目录下为floatboat帐号建立一个名为floatboat的主目录。如果你不想 使用这个缺省的目录，而希望把他的主目录放在/home/goal里(还放在/home下，只是一种良好的习惯，没有其他什么特别的要求)，可以使用  useradd的参数-d，命令如下：</p> <p>　　useradd -d /home/goal floatboat</p> <p>　　2、useradd的初始化操作还包括为用户单独建立一个与用户名同名的组(floatboat组)。这叫用户私有组的机制，与默认组机制相对 应。对用户分组一是方便管理，二是可以明确权限。复杂的我们将在以后的深入内容中探讨。我们如果想让此用户加入一个已有的组的话，可以使用-g参数。例如 我们想让floatboat加入webusers组，那么可以使用以下命令：</p> <p>　　useradd -g webusers floatboat</p> <p>　　同样的，我们还可以使用-G参数使他同时加入多个组，例如webusers和ftpusers：</p> <p>　　useradd -G ftpusers,webusers floatboat</p> <p>　　3、passwd命令为一个用户设置密码，但它实质上是一个修改密码的程序。只有超级用户和用户自己可以修改密码，其它的普通用户没有给他修改 密码的  权利。用户密码的组成要尽量的复杂，最好包括字母、数字和特殊符号，而且最好设成6位以上。太短passwd程序不允许，只是单纯的字母或单纯的数  字，passwd也会有意见。你都会看见passwd出现的提示的，不要害怕，仔细看看到底它是怎么说的：)</p> <p>　　4、你在增加一个新用户的时候，也可以设置用户登录的shell。缺省的，系统提供了/bin/bash。你如果非要指定的话，可以使用-s参数就可以了。例如</p> <p>　　useradd -d /www -s /usr/bin/passwd floatboat</p> <p>　　注意，这些参数是可以一块使用的，如上例所示，它表示增加新用户，并把其主目录路径设置在/www，登录的shell为/usr/bin/passwd。关于shell的更详细的说明，请参考下面的修改用户的个人设置相关内容。</p> <p>　　5、删除一个用户可以使用userdel命令，直接带用户名做参数就可以了。</p> <p><strong>　　修改用户的设置</strong></p> <p>　　对现有用户的修改，比较常用的主要是修改密码(使用passwd就好了)，修改用户的登录shell，修改用户所属的默认组，设置帐号有效期，修改用户的说明信息等等，偶尔也会用到修改用户主目录。</p> <p><strong>　　修改用户的登录shell</strong></p> <p>　　使用chsh命令可以修改自己的shell，只有超级用户才能用chsh username为其它用户修改shell设置。注意，指定的shell必须是列入/etc/shells文件中的shell，否则该用户将不能登陆。</p> <p>　　一般，比较常见的shells文件包括下面这些shell：</p> <p>　　/bin/bash2</p> <p>　　/bin/bash</p> <p>　　/bin/sh</p> <p>　　/bin/ash</p> <p>　　/bin/bsh</p> <p>　　/bin/tcsh</p> <p>　　/bin/csh</p> <p>　　而网管们还喜欢在里面加上/usr/bin/passwd，这是为了不然用户通过控制台或telnet登录系统，却可以使用修改帐户密码(比如在FTP里 用)。以及/bin/false，也就是不让这个用户登录的意思喽^&amp;^，连FTP也不能用。</p> <p>　　你也可以使用usermod命令修改shell信息，如下所示：</p> <p>　　usermod -s /bin/bash floatboat</p> <p>　　其中/bin/bash和floatboat应取相应的shell路径文件名及用户名。</p> <p>　　还有一种情况，就是你为用户设置了一个空的shell(就是"")，也就是说，这个用户没有shell。呵呵，绝对没有在我还未曾见过，因为这种用户登录后，系统还是会给它一个shell用的。不信你试试：</p> <p>　　usermod -s "" floatboat</p> <p>　　这种用户根据系统的不同，会有一个sh或bash进行操作，我也没有看出功能上和其它普通用户登录有什么不同。</p> <p>　　修改用户所属的默认组</p> <p>　　这个功能也可以通过usermod命令来实现，使用-g参数，例如把floatboat的默认组改为nobody，可以使用如下命令：</p> <p>　　usermod -g nobody floatboat</p> <p>　　nobody在类UNIX系统中一般都意味着没有任何权限。</p> <p>　　设置帐号有效期</p> <p>　　如果使用了影子口令，则可以使用如下命令来修改一个帐号的有效期：</p> <p>　　usermod -e MM/DD/YY username</p> <p>　　例如把用户floatboat的有效期定为2001年12月31日：</p> <p>　　usermod -e 12/31/01 floatboat</p> <p>　　如果把该用户的有效期设为已经过去的时间，就可以暂时禁止该用户登录系统。</p> <p>　　修改用户的说明信息</p> <p>　　修改用户的说明信息，最简单的方法莫过于直接修改/etc/passwd文件，找到对应的用户记录行，例如下列行：</p> <p>　　floatboat:x:503:503::/home/floatboat:/bin/bash</p> <p>　　你可以直接在第四个冒号和第五个冒号之间插入该用户的说明就可以了。其实，很多用户设置都可以在这修改，比如该行最后一部分/bin/bash就是用户登录shell的设置。关于这个/etc/passwd文件，我们后面将进一步的深入探讨。</p> <p>　　修改用户主目录</p> <p>　　修改用户的主目录主要使用usermod命令的-d参数，例如：</p> <p>　　usermod -d /www floatboat</p> <p>　　这一行将floatboat的主目录改到/www。如果想将现有主目录的主要内容转移到新的目录，应该使用-m开关，如下所示：</p> <p>　　usermod -d -m /www floatboat</p> <p>　　文件目录的权限</p> <p>　　linux下，每一个文件、每一个目录都有一个属主，并针对用户自己、用户所在组、其它所有帐号(组)分别设定读、写、执行三种权限。例如，我(假定是webusers组的floatboat帐户的拥有者)使用如下命令建立一个新的文件</p> <p>　　touch mytestfile</p> <p>　　然后我们使用ls -l mytestfile这一命令来查看这个文件的权限状态(关于ls命令，可以查阅本站的命令查询)，可以得到如下的屏幕输出显示：</p> <p>　　-rw-rw-r-- 1 floatboat webusers 0 Feb 6 21:37 mytestfile</p> <p>　　输出由空格分为9个部分，我们比较关心第一、三、四个字段，分别表示文件权限属性、文件所有者帐户、文件所属组。</p> <p><strong>　　&#9670;使用chown命令修改文件的主人</strong></p> <p>　　当你新建立一个文件的时候，文件的所有者当然就是你了。这一事实只有超级用户(比如说root)才可以通过chown命令改变(例如chown  otheruser  mytestfile,把mytestfile文件的属主改为otheruser)。普通用户不能把自己的文件&#8220;送&#8221;给别人，不然你把有特殊目的的程序给  了root怎么办？：)</p> <p>　　chown命令的用法比较简单。这里我先假设你现在拥有超级用户权限，那么你就可以使用如下命令将一个文件&#8220;送给&#8221;floatboat了：</p> <p>　　chown floatboat /home/floatboat/thefileisrootcreate.txt(假定该文件是由root创建的)</p> <p>　　修改一个目录的所有者也是类似的：</p> <p>　　chown floatboat /home/newboat</p> <p>　　当然，如果这个目录还有子目录及文件需要同时送给floatboat，chown也是支持-R参数的：</p> <p>　　chown -R floatboat /home/newboat</p> <p>　　如果你同时想修改文件/目录所属的组的话，你可以使用以下命令方便的达到目的：</p> <p>　　chown -R floatboat.ftpusers /home/newboat</p> <p>　　这样，不但文件主人得到了修改，文件所属的组也变成了ftpusers</p> <p><strong>　　&#9670;修改文件的组属性</strong></p> <p>　　文件所属组你倒是可以改变，前提是：</p> <p>　　1、你的超级用户。</p> <p>　　2、你同时属于两个或两个以上的组。</p> <p>　　两个条件你至少具备一个，你才能够把文件所属旧组变为新组。使用如下的命令将当前目录下所有html文件所属的组改为httpd：</p> <p>　　chgrp httpd *.html</p> <p>　　和chown命令一样，chgrp也可以使用-R参数对一个目录内的所有文件和子目录进行递归的修改组属性。</p> <p>　　&lt;提示&gt;：你可以使用不带参数的groups命令查看自己属于哪个组。</p> <p>　　文件权限的设定是我们这一小节讨论的核心，我们主要介绍chmod命令的两种用法。</p> <strong>&#9670;使用访问字符串设置文件目录权限</strong> <p>　　正如前面所说的，每一个文件、目录都针对用户自己、用户所在组、其它所有帐号(组)分别有读、写、执行三种权限及其组合。当一个普通用户新建一 个文件  的时候，它默认的访问权限显示就如我们刚才所举例子的第一个字段所示。总共十位字符&#8220;-rw-rw-r--&#8221;，第一位是目录区分标志，如果是d的话，表示  这是一个目录。第二到四位分别表示文件所有者的读(r：read)、写(w:write)、执行(x:execute)属性，第五到七位是文件所属组的   读、写、执行权限，第八到第十位则是其它用户的读、写、执行权限。如果对应的位是相应的字母，就是有这相应权限，否则为&#8220;-&#8221;，表示没有获得这个许可。象  刚才例子中的文件就是自己可读写，本组可读写，其它用户可读，所有的用户(包括自己)都不能执行它。</p> <p>　　我们的用u、g、o分别来指代用户(user)、组(group)、其它帐户(other)，就可以方便的设置文件和目录的权限了。当然，我们也可以用a来表示所有的这三项。</p> <p>　　例如，我们要对所有perl的脚本文件设定权限，对所有用户都可以读和执行，文件所有者还允许写许可，那么我们可以使用如下命令：</p> <p>　　chmod a+rx,u+w *.pl</p> <p>　　注意：如果要使用多个访问字符串，它们之间要用逗号隔开，各个许可字符串之间不允许有空格。正如上例所示。</p> <p>　　如果要修改目录中所有文件和子目录的权限属性，可以使用chmod提供的-R参数来递归修改。例如，下列命令将/www/site1目录及其下面的子目录的权限属性设定为所有者和组可读、写、执行，其它用户不可访问：</p> <p>　　chmod -R a+rwx,o-rwd /www/site1</p> <p>　　注意，不要轻易使用-R选项，这可能会带来安全隐患。</p> <p>　　使用字符串方便了理解，单输入那么多字母还是有点累，如果你对8进制有些概念的话，可以使用下面介绍的方法来做权限设置。</p> <p><strong>　　&#9670;使用八进制数设置文件目录权限</strong></p> <p>　　我们知道，在ls  -l的输出中，文件权限表示为&#8220;-rw-rw-r--&#8221;，前一位只和是否为目录有关，其它九位正好可以分成三段，每段三位，&#8220;rw-&#8221;、&#8220;rw-&#8221;和  &#8220;r--&#8221;,&#8220;-&#8221;代表无效&#8220;0&#8221;，其它字符代表有效&#8220;1&#8221;，那么这个文件的权限就是&#8220;110&#8221;、&#8220;110&#8221;、&#8220;100&#8221;，把这个2进制串转换成对应的8   进制数就是6、6、4，也就是说该文件的权限为664(三位八进制数)。我们也可以使用类似这种三位八进制数来设定文件授权，如上边两个例子，就也可以写  为：</p> <p>　　chmod 755 *.pl</p> <p>　　chmod -R 770 /www/site1</p> <p>　　是不是很简洁？关键在于你能根据你需要设定的权限正确的选择八进制数(利用八进制数的二进制表示可以非常轻易的做到这一点)。</p> <p><strong>　　&#9670;读、写、执行的权限说明</strong></p> <p>　　1、所谓写的权限，也就是对文件修改和删除的权限。如果目录的写权限也对你开放了，则可以创建、删除或修改该目录下的任何文件或自目录&#8212;&#8212;即使该文件和子目录并不属于你。</p> <p>　　2、对目录有只读许可的用户，不能用cd命令进入该目录;还必须同时有执行许可才可以进入该目录。</p> <p>　　3、必须同时拥有读和执行权限才可以使用ls这样的程序列出目录内容清单。</p> <p>　　4、只对目录有执行权限的用户，想访问该目录下的文件有读权限的文件，必须知道该文件名才可以访问。</p> <p>　　两个重要文件：passwd与group</p> <p>　　在linux的安全机制里，/etc/passwd与/etc/group这两个文件占着非常重要的地位。它们控制着linux的用户和组一些重要设置。</p> <p><strong>　　&#9670;/etc/passwd文件说明</strong></p> <p>　　下面是一个RHlinux里普通的passwd文件的例子：</p> <p>　　root:x:0:0:root:/root:/bin/bash</p> <p>　　bin:x:1:1:bin:/bin:</p> <p>　　daemon:x:2:2:daemon:/sbin:</p> <p>　　&#8230;&#8230;</p> <p>　　operator:x:11:0perator:/root:</p> <p>　　games:x:12:100:games:/usr/games:</p> <p>　　gopher:x:13:30:gopher:/usr/lib/gopher-data:</p> <p>　　ftp:x:14:50:FTP User:/home/ftp:</p> <p>　　nobody:x:99:99:Nobody:/:</p> <p>　　xfs:x:43:43:X Font Server:/etc/X11/fs:/bin/false</p> <p>　　named:x:25:25:Named:/var/named:/bin/false</p> <p>　　postgres:x:26:26ostgreSQL Server:/var/lib/pgsql:/bin/bash</p> <p>　　lanf:x:500:500::/home/hujm:/bin/bash</p> <p>　　mysql:x:101:101:MySQL server:/var/lib/mysql:/bin/bash</p> <p>　　imnotroot:x:0:0::/home/imnotroot:/bin/bash</p> <p>　　在这个文件里只有一个普通帐号lanf。其它都是系统或系统服务的进程需要的帐号，包括我们非常熟悉的root这个超级用户。在passwd的文件里，每一行被冒号(":")分成7个部分，分别是：</p> <p>　　[用户名]：[密码]：[UID]：[GID]：[身份描述]：[主目录]：[登录shell]</p> <p>　　其中：</p> <p>　　&#9352;[用户名]是passwd文件里各记录行唯一的有"唯一性"要求的域。也就是说每一行的第一个区域的内容都不能相同，其它区域就无所谓了。</p> <p>　　&#9353;[密码]区域在以前，保存着一个经过不可逆的哈希算法进行DES加密的13位字符，但不包括单引号和冒号。这13位字符中，前两位是密钥，在 加密的  时候随机生成的。由于这个字符串不包括单引号，所以以前有一种不修改密码又禁止用户登录的方式就是在密码前面加一个单引号。值得注意的是，现在由于使用了  shadow口令，在密码区域只有一个x字符。</p> <p>　　&#9354;[UID]虽然是系统用来标志文件归属，确定各种权限的标志，但这个区域的内容并不要求唯一的。比较常见而又与安全问题相关的一个例子是有多 个  UID和GID均为0的用户帐号。注意到在该文件最后一行还有一个UID和GID为0的用户imnotroot，虽然它声称自己不是root，但是它却有   和root完全相同的权限，因为系统并非根据[用户名]，而是根据UID和GID来分用户的权力的。所以，这种情况无疑为系统埋下了安全的zhadan。 但是，当  imnorroot做锁定屏幕等操作的时候，如果它的密码和root的不一样，它将无法解锁，因为系统只是查到第一个UID为0的用户(自然是root)  后，就不在往下查找了&#8212;&#8212;它当UID也是唯一的。</p> <p>　　&#9355;[GID]用户默认的组ID，这个ID可以在文件/etc/group里查到对应的组名。</p> <p>　　&#9356;[身份描述]：就是用户的身份说明，默认的是无任何说明，可人工添加。</p> <p>　　&#9357;[主目录]：用户的主目录，可以使用前面介绍的命令修改。</p> <p>　　&#9358;[登录shell]：用户登录时系统提供的shell，请参考前面的有关内容。</p> <p>　　&lt;注意&gt;：[UID]和[GID]小于500的一般都是系统自己保留，不做普通用户和组的标识的，所以新增加的用户和组一般都是UID和GID大于500的。</p> <p><strong>　　&#9670;/etc/group文件说明</strong></p> <p>　　下面是RH的一个group文件的例子：</p> <p>　　root:x:0:root,hujm,hjm</p> <p>　　bin:x:1:root,bin,daemon</p> <p>　　daemon:x:2:root,bin,daemon</p> <p>　　sys:x:3:root,bin,adm</p> <p>　　adm:x:4:root,adm,daemon</p> <p>　　tty:x:5:</p> <p>　　disk:x:6:root</p> <p>　　lp:x:7:daemon,lp</p> <p>　　mem:x:8:</p> <p>　　kmem:x:9:</p> <p>　　wheel:x:10:root</p> <p>　　mail:x:12:mail</p> <p>　　news:x:13:news</p> <p>　　uucp:x:14:uucp</p> <p>　　&#8230;&#8230;</p> <p>　　hujm:x:503:root,mynoshell,hjm</p> <p>　　mysql:x:101:</p> <p>　　mynoshell:x:505:</p> <p>　　ftpusers:x:506:</p> <p>　　它总共分四个部分：</p> <p>　　[组名]：[密码域]：[GID]：[组员列表]</p> <p>　　意思非常明显，需要说明一下的是，由于组一般都不用密码保护，所以虽然看起来密码域有个X字符，其实那只表示使用了SHADOW(对应文件为  gshadow)。组员列表用逗号分隔各个帐号。另外，一个组的组员如果默认登录组就是它的话，那么在组员列表里将不显示这个组员的帐号，例如用如下命令  增加的用户：</p> <p>　　useradd -g ftpusers floatboat</p> <p>　　在/etc/group文件里ftpusers的组员列表将不显示这个组员(真是失败)，而只是在passwd文件中的GID被设置为506。而使用如下命令：</p> <p>　　usermod -G ftpusers,mysql,webusers floatboat</p> <p>　　就可以看见相关的组后边加上了floatboat帐号。当然，你可以直接用vi来直接编辑这个文件。</p> <p>　　group文件和passwd文件是通过GID联系在一起的，这有点象关系数据库。根据passwd文件中一个帐户的GID，可以在group 文件中  找到对应的组名。如果采用了用户私有组机制的话，那么一般新增一个帐号，就会有对应的一个与帐号同名的组增加到group文件中。虽然这时passwd文   件中具有唯一性的[用户名]字段和group文件中具有唯一性的[组名]字段一样，并不代表着它们是通过这两个字段形成一一对应的关系的。千万别忘记，系  统对数字(UID，GID)更加敏感.</p></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/196050.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-12-06 19:22 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/12/06/196050.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Too many open files -- linux文件描述符的限制调整 </title><link>http://www.cppblog.com/guojingjia2006/archive/2012/11/21/195450.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Wed, 21 Nov 2012 03:43:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/11/21/195450.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/195450.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/11/21/195450.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/195450.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/195450.html</trackback:ping><description><![CDATA[<div><span style="font-size:16px"> 转自:<div>http://blog.csdn.net/yetyongjin/article/details/7476860</div><br />这两天做asterisk的性能测试，经常碰到这样的错误：&#8220;Too many open files&#8221;。</span> <p style="background:#FAFAFA"><span style="font-size:16px">&nbsp; &nbsp; &nbsp; &nbsp;  我们知道，Linux下，文件描述符就是一个简单的整数值，习惯上，标准输入（standard input）的文件描述符是  0，标准输出（standard output）是 1，标准错误（standard error）是 2。POSIX  定义了STDIN_FILENO、STDOUT_FILENO 和STDERR_FILENO 来代替 0、1、2。这三个符号常量的定义位于头文件  unistd.h。</span></p> <p><span style="font-size:16px">&nbsp; &nbsp; &nbsp; &nbsp; 文件描述符的有效范围是0 到OPEN_MAX。那么一个进程最多到底能打开多少个文件描述符呢？下面，就以asterisk进程为例来说明。</span></p> <p><span style="font-size:16px"><br /> </span></p> <p><strong><em><span style="background:#D9D9D9"><span style="font-size:16px">#ps &#8211;ef | grep asterisk</span></span></em></strong></p> <p><strong><em><span style="background:#D9D9D9"><span style="font-size:16px"><img src="http://my.csdn.net/uploads/201204/19/1334806915_6581.jpg" alt="" /><br /> </span></span></em></strong></p>  <p><span style="font-size:16px">从第二列得到asterisk的PID为19488。</span></p> <p><strong><em><span style="background:#D9D9D9"><span style="font-size:16px"># cat /proc/19488/limits</span></span></em></strong></p> <p><img src="http://my.csdn.net/uploads/201204/19/1334806942_4679.jpg" alt="" /></p> <p><span style="font-size:16px">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="font-size:16px">红线一行说明asterisk进程最大能打开1024个文件描述符（不包含它的子进程或创建出来的线程）。在/proc/19488/task/目录下，详细列出了其下的子任务的情况，每个子文件夹里同样有一个limits文件，限定了各子任务的情况。</span></p> <p>&nbsp;</p> <p><span style="font-size:16px">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;一个进程打开了几个文件描述符呢？</span></p> <p><strong><em><span style="background:#D9D9D9"><span style="font-size:16px"># ll /proc/19488/fd/</span></span></em></strong></p> <p><strong><em><span style="background:#D9D9D9"><span style="font-size:16px"><img src="http://my.csdn.net/uploads/201204/19/1334806999_3990.jpg" alt="" /><br /> </span></span></em></strong></p>  <p><span style="font-size:16px">&nbsp; &nbsp; &nbsp; &nbsp; 子目录fd中，详细列出了进程打开的每个文件描述符，同样，/proc/19488/task/XXXX/fd下也会有子任务打开的文件描述符的情况。要知道有几个，执行</span></p> <p><strong><em><span style="background:#D9D9D9"><span style="font-size:16px"># ll /proc/19488/fd/ | wc -l</span></span></em></strong></p> <p>&nbsp;</p> <p><span style="font-size:16px">&nbsp; &nbsp; &nbsp; &nbsp; 怎样知道一个进程及其子进程和哪些文件有关联呢？lsof可以完成这工作。请注意，关联文件和打开文件描述符是两个不同的概念，关联文件的数量可能远远大于打开的文件描述符的数量。</span></p> <p><strong><em><span style="background:#D9D9D9"><span style="font-size:16px"># lsof | grep asterisk | wc &#8211;l</span></span></em></strong></p> <p><span style="font-size:16px">&nbsp; &nbsp; &nbsp; &nbsp; 也可以用父进程的PID过滤</span></p> <p><strong><em><span style="background:#D9D9D9"><span style="font-size:16px"># lsof | grep 19488 | wc &#8211;l</span></span></em></strong></p> <p><span style="font-size:16px">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;我这里得到的值是9525</span></p> <p>&nbsp;</p> <p><span style="font-size:16px">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;怎样修改文件描述符的限定呢？临时修改，可以通过ulimit。</span></p> <p><strong><em><span style="background:#D9D9D9"><span style="font-size:16px"># ulimit -SHn 2048</span></span></em></strong></p> <p>&nbsp;</p> <p><span style="font-size:16px">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 但是这样只能影响到当前的session，当终端重新连接或当前用户退出，配置就失效了。如果想永久变更需要编辑/etc/security/limits.conf 文件，添加如下两行：<br /> * hard nofile 2048<br /> * soft nofile 2048</span></p> <p>&nbsp;</p> <p><span style="font-size:16px">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="font-size:16px">内核参数对文件描述符也有限制，如果设置的值大于内核的限制，也是不行的：</span></p> <p><span style="font-size:16px">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;查找file-max的内核参数：</span></p> <p><strong><em><span style="background:#D9D9D9"><span style="font-size:16px"># sysctl -a|grep file-max</span></span></em></strong></p> <p><span style="font-size:16px">&nbsp; &nbsp; &nbsp; &nbsp; 更改file-max的内核参数：</span></p> <p><strong><em><span style="background:#D9D9D9"><span style="font-size:16px"># sysctl -w file-max=65535</span></span></em></strong></p> <p><span style="font-size:16px">&nbsp; &nbsp; &nbsp; &nbsp; Sysctl也是临时的，要想永久生效，可以通过更改sysctl的文件，编辑/etc/sysctl.conf文件，添加或修改以下一行：</span></p> <p><span style="font-size:16px">fs.file-max=65535</span></p> <p>&nbsp;</p> <p><span style="font-size:16px">&nbsp; &nbsp; &nbsp; &nbsp; 需要注意的是，文件描述符的限制，不局限于这里描述的这些，还可能和进程的启动参数、用户的环境设置有关。当然，如果是进程BUG造成文件描述符没有及时关闭回收，这增大限制也只是治标，根本上还得修复BUG。</span></p> <p><span style="font-family:微软雅黑,Verdana,sans-serif,宋体; font-size:14px; line-height:24px; text-align:left">&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="font-size:16px"><span style="font-family:微软雅黑,Verdana,sans-serif,宋体; line-height:24px; text-align:left">此外，lsof会列出系统中所占用的资源,但是这些资源不一定会占用打开的文件描述符(</span><span style="padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; text-align:left; font-family:simsun; line-height:23px">比如共享内存,信号量,消息队列,内存映射.等,虽然占用了这些资源,但不占用打开文件号)</span><span style="font-family:微软雅黑,Verdana,sans-serif,宋体; line-height:24px; text-align:left">，因此有可能出现</span><span style="padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; text-align:left; font-family:simsun; line-height:23px">cat  /proc/sys/fs/file-max</span><span style="padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; text-align:left; font-family:simsun; line-height:23px">&nbsp;的值小于lsof | wc -l。asterisk本身提供了一个启动脚本，名为safe_asterisk，脚本里面就对文件描述符做了一些设置。</span></span></p></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/195450.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-11-21 11:43 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/11/21/195450.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysqldump</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/08/01/185869.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Wed, 01 Aug 2012 04:23:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/08/01/185869.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/185869.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/08/01/185869.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/185869.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/185869.html</trackback:ping><description><![CDATA[<div><div> <p><span style="font-size: medium;"><strong>命令行下具体用法如下：&nbsp; </strong></span></p> <p><span style="font-size: medium;"><strong>mysqldump -u用戶名 -p密码 <span style="color: #ff0000;">-d</span> 数据库名&nbsp;表名 &gt; 脚本名;</strong></span></p> <p>&nbsp;</p> <p>&nbsp;</p> <p><span style="font-size: medium;">导出整个数据库结构和数据<br />mysqldump -h localhost -uroot -p123456&nbsp;database &gt; dump.sql</span></p> <p>&nbsp;</p> <p><span style="font-size: medium;">导出单个数据表结构和数据<br />mysqldump -h localhost -uroot -p123456&nbsp; database table &gt; dump.sql</span></p> <p>&nbsp;</p> <p>&nbsp;</p> <div> <p><span style="color: #000000; font-size: medium;">导出整个数据库结构（不包含数据）<br />mysqldump -h localhost -uroot -p123456&nbsp;<span> -d&nbsp;database &gt; dump.sql</span></span></p> <p>&nbsp;</p> <p><span style="color: #000000; font-size: medium;">导出单个数据表结构（不包含数据）<br />mysqldump -h localhost -uroot -p123456&nbsp; <span>-d&nbsp;database table &gt; dump.sql</span></span></p> </div> </div></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/185869.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-08-01 12:23 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/08/01/185869.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Apache Rewrite 注意点</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/07/20/184384.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Fri, 20 Jul 2012 11:54:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/07/20/184384.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/184384.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/07/20/184384.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/184384.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/184384.html</trackback:ping><description><![CDATA[<div><p>1.首先配置apache的httpd.conf，目的是使.htaccess文件生效<br />&lt;VirtualHost a.b.c.d&gt;<br />&nbsp;&nbsp;&nbsp; ServerAdmin a<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#97;&#64;&#98;&#46;&#99;&#111;&#109;">@b.com</a><br />&nbsp;&nbsp;&nbsp; DocumentRoot /var/www/bulknews<br />&nbsp;&nbsp;&nbsp; ServerName <a href="http://www.bulknews.cn">www.bulknews.cn</a><br />&lt;Directory /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Options FollowSymLinks<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AllowOverride All<br />&lt;/Directory&gt;<br />ErrorLog&nbsp; "|/usr/local/sbin/cronolog /var/log/www/wapya/www.bulknews.cn_error_log.%Y%m%d"<br />CustomLog "|/usr/local/sbin/cronolog /var/log/www/wapya/www.bulknews.cn_access_log.%Y%m%d" combined<br />&lt;/VirtualHost&gt;</p> <p>注意，这里必须是FollowSymLinks，AllowOverride是All，否则rewrite引擎根本不起作用，另外如果你的apache默认根目录是/var/www 的话，在/var/www的配置字段也要设置<br />Options FollowSymLinks<br />&nbsp;AllowOverride All<br />我的就因为这个，只是在虚拟主机设置，导致一直不能实现静态页面的转化。</p> <p>2.在/var/www/bulknews下设置.htaccess文件<br />我们这边最简单的配置就是<br />RewriteEngine&nbsp;&nbsp; on<br />RewriteBase&nbsp;&nbsp;&nbsp;&nbsp; /<br />RewriteRule&nbsp;&nbsp;&nbsp;&nbsp; (.+)\.html$ show.php?id=$1 [L]</p> OK，重启web服务，这时候你就可以正常访问<a href="http://www.bulknews.cn/1014700.html">http://www.bulknews.cn/1014700.html</a><br /><br />另外rewrite还有很多应用，大家可以多去google找一些资料，功能还是很神奇的。</div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/184384.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-07-20 19:54 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/07/20/184384.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>安装 Git 版本控制工具 </title><link>http://www.cppblog.com/guojingjia2006/archive/2012/07/17/183952.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Tue, 17 Jul 2012 13:54:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/07/17/183952.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/183952.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/07/17/183952.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/183952.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/183952.html</trackback:ping><description><![CDATA[RHEL/Fedora/CentOS yum 安装<div><strong></strong>  		<div id="crayon-50056b042b1ab" crayon-theme-phiphou="" crayon-font-courier-new="" crayon-os-pc=""  print-yes"="" data-settings=" scroll-mouseover" style=" margin-top: 12px; margin-bottom: 12px; float: none; clear: both; "> 		 			 			 			<div><textarea wrap="off"  print-no"="" data-settings="dblclick" readonly="readonly" style="-moz-tab-size: 4; z-index: 0; opacity: 0; overflow: hidden; height: 15px;">yum install git git-svn git-email git-gui gitk</textarea></div> 			<div style="position: relative; z-index: 1; overflow: hidden;"> 				<table> 					<tbody><tr> 				<td "="" data-settings="show"> 					<div><div>1</div></div> 				</td> 						<td><div><div id="crayon-50056b042b1ab-1">yum install git git-svn git-email git-gui gitk</div></div></td> 					</tr> 				</tbody></table> 			</div> 		</div>  <p><strong>从源代码进行编译安装</strong></p> <p>1. 先下载最新的 git 稳定版源码</p>  		<div id="crayon-50056b042b58d" crayon-theme-phiphou="" crayon-font-courier-new="" crayon-os-pc=""  print-yes"="" data-settings=" scroll-mouseover" style=" margin-top: 12px; margin-bottom: 12px; float: none; clear: both; "> 		 			 			 			<div><textarea wrap="off"  print-no"="" data-settings="dblclick" readonly="readonly" style="-moz-tab-size: 4; z-index: 0; opacity: 0; overflow: hidden; height: 15px;">wget https://git-core.googlecode.com/files/git-1.7.10.tar.gz</textarea></div> 			<div style="position: relative; z-index: 1; overflow: hidden;"> 				<table> 					<tbody><tr> 				<td "="" data-settings="show"> 					<div><div>1</div></div> 				</td> 						<td><div><div id="crayon-50056b042b58d-1">wget https://git-core.googlecode.com/files/git-1.7.10.tar.gz</div></div></td> 					</tr> 				</tbody></table> 			</div> 		</div>  <p>2. 解压源码，并进入源码目录</p>  		<div id="crayon-50056b042b98d" crayon-theme-phiphou="" crayon-font-courier-new="" crayon-os-pc=""  print-yes"="" data-settings=" scroll-mouseover" style=" margin-top: 12px; margin-bottom: 12px; float: none; clear: both; "> 		 			<div data-settings=" mouseover overlay hide delay" style="margin-top: -15.5607px; display: block; z-index: 4;"> 			<div>PHP</div></div> 			 			<div><textarea wrap="off"  print-no"="" data-settings="dblclick" readonly="readonly" style="-moz-tab-size: 4; z-index: 0; opacity: 0; overflow: hidden; height: 30px;">tar xzvf git-1.7.10.tar.gz cd git-1.7.10</textarea></div> 			<div style="position: relative; z-index: 1; overflow: hidden;"> 				<table> 					<tbody><tr> 				<td "="" data-settings="show"> 					<div><div>1</div><div crayon-striped-num"="">2</div></div> 				</td> 						<td><div><div id="crayon-50056b042b98d-1">tar xzvf git-1.7.10.tar.gz </div><div crayon-striped-line"="" id="crayon-50056b042b98d-2">cd git-1.7.10</div></div></td> 					</tr> 				</tbody></table> 			</div> 		</div>  <p>3. 编译安装</p>  		<div id="crayon-50056b042bdc7" crayon-theme-phiphou="" crayon-font-courier-new="" crayon-os-pc=""  print-yes"="" data-settings=" scroll-mouseover" style=" margin-top: 12px; margin-bottom: 12px; float: none; clear: both; "> 		 			 			 			<div><textarea wrap="off"  print-no"="" data-settings="dblclick" readonly="readonly" style="-moz-tab-size: 4; z-index: 0; opacity: 0; overflow: hidden; height: 30px;">./configure prefix=/usr/local make &amp;&amp; make install</textarea></div> 			<div style="position: relative; z-index: 1; overflow: hidden;"> 				<table> 					<tbody><tr> 				<td "="" data-settings="show"> 					<div><div>1</div><div crayon-striped-num"="">2</div></div> 				</td> 						<td><div><div id="crayon-50056b042bdc7-1">./configure prefix=/usr/local </div><div crayon-striped-line"="" id="crayon-50056b042bdc7-2">make &amp;&amp; make install</div></div></td> 					</tr> 				</tbody></table> 			</div> 		</div>  <p>可能出现的错误：</p> <p>a. msgfmt: command not found</p> <p>解决方法：yum install gettext</p> <p>b. 安装完毕执行git，提示&#8220;git: error while loading shared libraries:  libcharset.so.1: cannot open shared object file: No such file or  directory&#8221;</p> <p>解决方法：ln -s /usr/local/lib/libcharset.so.1 /lib/libcharset.so.1</p> <p>4. 安装 Git 命令补全功能</p> <p>a. 复制命令补全脚本到 /etc/bash_completion.d/ 目录（没有则自行创建）</p>  		<div id="crayon-50056b042c1a9" crayon-theme-phiphou="" crayon-font-courier-new="" crayon-os-pc=""  print-yes"="" data-settings=" scroll-mouseover" style=" margin-top: 12px; margin-bottom: 12px; float: none; clear: both; "> 		 			 			 			<div><textarea wrap="off"  print-no"="" data-settings="dblclick" readonly="readonly" style="-moz-tab-size: 4; z-index: 0; opacity: 0; overflow: hidden; height: 15px;">cp contrib/completion/git-completion.bash /etc/</textarea></div> 			<div style="position: relative; z-index: 1; overflow: hidden;"> 				<table> 					<tbody><tr> 				<td "="" data-settings="show"> 					<div><div>1</div></div> 				</td> 						<td><div><div id="crayon-50056b042c1a9-1">cp contrib/completion/git-completion.bash /etc/</div></div></td> 					</tr> 				</tbody></table> 			</div> 		</div>  <p>b. 载入 git 命令自动补全脚本，使之在当前的 shell 环境中生效</p>  		<div id="crayon-50056b042c584" crayon-theme-phiphou="" crayon-font-courier-new="" crayon-os-pc=""  print-yes"="" data-settings=" scroll-mouseover" style=" margin-top: 12px; margin-bottom: 12px; float: none; clear: both; "> 		 			 			 			<div><textarea wrap="off"  print-no"="" data-settings="dblclick" readonly="readonly" style="-moz-tab-size: 4; z-index: 0; opacity: 0; overflow: hidden; height: 15px;">. /etc/git-completion.bash</textarea></div> 			<div style="position: relative; z-index: 1; overflow: hidden;"> 				<table> 					<tbody><tr> 				<td "="" data-settings="show"> 					<div><div>1</div></div> 				</td> 						<td><div><div id="crayon-50056b042c584-1">. /etc/git-completion.bash</div></div></td> 					</tr> 				</tbody></table> 			</div> 		</div>  <p>这时候你就会发现自动补全已经生效了。试试输入&#8221;git com&#8221;, 再按下 TAB 键看看吧。<br /> c. 为了命令补全功能能在下次启动终端时自动启用，需要在 /etc/profile 与 ~/.bashrc 中添加如下内容：</p>  		<div id="crayon-50056b042c96c" crayon-theme-phiphou="" crayon-font-courier-new="" crayon-os-pc=""  print-yes"="" data-settings=" scroll-mouseover" style=" margin-top: 12px; margin-bottom: 12px; float: none; clear: both; "> 		 			 			 			<div><textarea wrap="off"  print-no"="" data-settings="dblclick" readonly="readonly" style="-moz-tab-size: 4; z-index: 0; opacity: 0; overflow: hidden; height: 60px;"># Git commands autocompletion if [ -f /etc/git-completion.bash ]; then     . /etc/git-completion.bash fi</textarea></div> 			<div style="position: relative; z-index: 1; overflow: hidden;"> 				<table> 					<tbody><tr> 				<td "="" data-settings="show"> 					<div><div>1</div><div crayon-striped-num"="">2</div><div>3</div><div crayon-striped-num"="">4</div></div> 				</td> 						<td><div><div id="crayon-50056b042c96c-1"># Git commands autocompletion </div><div crayon-striped-line"="" id="crayon-50056b042c96c-2">if [ -f /etc/git-completion.bash ]; then </div><div id="crayon-50056b042c96c-3">&nbsp;&nbsp;&nbsp;&nbsp;. /etc/git-completion.bash </div><div crayon-striped-line"="" id="crayon-50056b042c96c-4">fi</div></div></td> 					</tr> 				</tbody></table> 			</div> 		</div>  <p><strong>附：Windows 环境使用 Git 的相关工具</strong></p> <p>1. Cygwin&nbsp;http://www.cygwin.com/</p> <p>2. msysGit&nbsp;http://msysgit.github.com/</p> <p>3. TortoiseGit http://code.google.com/p/tortoisegit/</p></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/183952.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-07-17 21:54 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/07/17/183952.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>nginx启动，重启，关闭命令</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/06/28/180622.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Thu, 28 Jun 2012 03:15:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/06/28/180622.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/180622.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/06/28/180622.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/180622.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/180622.html</trackback:ping><description><![CDATA[<div><div id="cnblogs_post_body"><div><strong style="line-height: normal;">停止操作<br style="line-height: normal;" /> </strong>停止操作是通过向nginx进程发送信号（什么是信号请参阅linux文 章）来进行的<br style="line-height: normal;" /> <span style="line-height: normal; text-decoration: underline;">步骤1：查询nginx主进程号<br style="line-height: normal;" /> <span style="line-height: normal; color: #0000ff;">ps -ef | grep nginx<br style="line-height: normal;" /> </span>在进程列表里 面找master进程，它的编号就是主进程号了。<br style="line-height: normal;" /> <span style="line-height: normal; text-decoration: underline;">步骤2：发送信号</span><br style="line-height: normal;" /> 从容停止Nginx：<br style="line-height: normal;" /> <span style="line-height: normal; color: #0000ff;">kill -QUIT 主进程号</span><br style="line-height: normal;" /> 快速停止Nginx：<br style="line-height: normal;" /> <span style="line-height: normal; color: #0000ff;">kill -TERM 主进程号</span><br style="line-height: normal;" /> 强制停止Nginx：<br style="line-height: normal;" /> <span style="line-height: normal; color: #0000ff;">pkill -9 nginx<br style="line-height: normal;" /> </span><br style="line-height: normal;" /> 另外， 若在nginx.conf配置了pid文件存放路径则该文件存放的就是Nginx主进程号，如果没指定则放在nginx的logs目录下。有了pid文 件，我们就不用先查询Nginx的主进程号，而直接向Nginx发送信号了，命令如下：<br style="line-height: normal;" /> <span style="line-height: normal; color: #0000ff;">kill  -信号类型 '/usr/nginx/logs/nginx.pid'</span><br style="line-height: normal;" /> <br style="line-height: normal;" /> <strong style="line-height: normal;">平滑重启</strong><br style="line-height: normal;" /> 如果更改了配置就要重启Nginx，要先关闭Nginx再打开？不是的，可以向Nginx 发送信号，平滑重启。<br style="line-height: normal;" /> <span style="line-height: normal; text-decoration: underline;">平滑重启命令：</span><br style="line-height: normal;" /> <span style="line-height: normal; color: #0000ff;">kill -HUP 住进称号或进程号文件路径<br /></span></span><p>或者使用</p> <p><span style="line-height: normal; color: #0000ff;">/usr/nginx/<span style="color: #0000ff;">sbin/nginx -s reload</span><br /></span></p><p> </p><p> </p> 注意，修改了配置文件后最好先检查一下修改过的配置文件是否正 确，以免重启后Nginx出现错误影响服务器稳定运行。判断Nginx配置是否正确命令如下：<br style="line-height: normal;" /> <span style="line-height: normal; color: #0000ff;">nginx  -t -c /usr/nginx/conf/nginx.conf<br /></span><p>或者</p><span style="line-height: normal; color: #0000ff;">/usr/nginx/<span style="color: #0000ff;">sbin/nginx -t<br /></span></span><p> </p> <br style="line-height: normal;" /> <strong style="line-height: normal;">平滑升级<br style="line-height: normal;" /> </strong>如果服务器正在运行的Nginx要进行升级、添加或删除模块时，我们需 要停掉服务器并做相应修改，这样服务器就要在一段时间内停止服务，Nginx可以在不停机的情况下进行各种升级动作而不影响服务器运行。<br style="line-height: normal;" /> <span style="line-height: normal; text-decoration: underline;">步骤1：<br style="line-height: normal;" /> 如 果升级Nginx程序，先用新程序替换旧程序文件，编译安装的话新程序直接编译到Nginx安装目录中。<br style="line-height: normal;" /> <span style="line-height: normal; text-decoration: underline;">步 骤2：执行命令</span><br style="line-height: normal;" /> <span style="line-height: normal; color: #0000ff;">kill -USR2 旧版程序的主进程号或进程文件名</span><br style="line-height: normal;" /> 此时旧的Nginx主进程将会把自己的进程文件改名为.oldbin，然后执行新版 Nginx。新旧Nginx会同市运行，共同处理请求。<br style="line-height: normal;" /> 这时要逐步停止旧版 Nginx，输入命令：<br style="line-height: normal;" /> kill -WINCH 旧版主进程号<br style="line-height: normal;" /> 慢慢旧的工作进程就都会随着任务执行完毕而退出，新版的Nginx的工作进程会逐渐取代旧版 工作进程。<br style="line-height: normal;" /> <br style="line-height: normal;" /> 此 时，我们可以决定使用新版还是恢复到旧版。<br style="line-height: normal;" /> 不重载配置启动新/旧工作进程<br style="line-height: normal;" /> kill -HUP 旧/新版主进程号<br style="line-height: normal;" /> 从容关闭旧/新进程<br style="line-height: normal;" /> kill -QUIT 旧/新主进程号<br style="line-height: normal;" /> 如果此时报错，提示还有进程没有结束就用下面命令先关闭旧/新工作进程，再关闭主进程号：<br style="line-height: normal;" /> kill -TERM 旧/新工作进程号<br /> </span><br style="line-height: normal;" /> 这样下来，如果要恢复到旧版本，只需要上面的几个步 骤都是操作新版主进程号，如果要用新版本就上面的几个步骤都操作旧版主进程号就行了。<br style="line-height: normal;" /> <br style="line-height: normal;" /> 上面就是Nginx的一些基本的操作，希望以后Nginx能有更好的方法来处理这些操作， 最好是Nginx的命令而不是向Nginx进程发送系统信号。</div></div></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/180622.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-06-28 11:15 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/06/28/180622.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux 下 apache启动、停止、重启命令</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/06/28/180621.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Thu, 28 Jun 2012 03:15:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/06/28/180621.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/180621.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/06/28/180621.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/180621.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/180621.html</trackback:ping><description><![CDATA[<div><p><strong>基本的操作方法：</strong><br /> 本文假设你的apahce安装目录为/usr/local/apache2，这些方法适合任何情况</p> <p>apahce启动命令：<br /> 推荐/usr/local/apache2/bin/apachectl start apaceh启动</p> <p>apache停止命令<br /> /usr/local/apache2/bin/apachectl stop&nbsp;&nbsp; 停止</p> <p>apache重新启动命令：<br /> /usr/local/apache2/bin/apachectl restart 重启</p> <p>要在重启 Apache 服务器时不中断当前的连接，则应运行：</p> <p>/usr/local/sbin/apachectl graceful</p> <p><strong>如果apache安装成为linux的服务的话，可以用以下命令操作：</strong></p> <p>service httpd start 启动</p> <p>service httpd restart 重新启动</p> <p>service httpd stop 停止服务</p></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/180621.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-06-28 11:15 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/06/28/180621.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows完成端口与Linux epoll技术简介(转载)</title><link>http://www.cppblog.com/guojingjia2006/archive/2010/08/27/124945.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Fri, 27 Aug 2010 07:43:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2010/08/27/124945.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/124945.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2010/08/27/124945.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/124945.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/124945.html</trackback:ping><description><![CDATA[<span style="font-size: 8pt;">
<p style="font-family: courier new;"><strong>WINDOWS完成端口编程<br>
</strong>1、基本概念<br>
2、WINDOWS完成端口的特点<br>
3、完成端口（Completion Ports ）相关数据结构和创建<br>
4、完成端口线程的工作原理<br>
5、Windows完成端口的实例代码<br>
<strong>Linux的EPoll模型<br>
</strong>1、为什么select落后<br>
2、内核中提高I/O性能的新方法epoll<br>
3、epoll的优点<br>
4、epoll的工作模式 <br>
5、epoll的使用方法<br>
6、Linux下EPOll编程实例<br>
<strong>总结</strong></p>
<p style="font-family: courier new;"><strong>WINDOWS完成端口编程<br>
</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
摘要：开发网络程序从来都不是一件容易的事情，尽管只需要遵守很少的一些规则;创建socket,发起连接，接受连接，发送和接受数据。真正的困难在于：
让你的程序可以适应从单单一个连接到几千个连接乃至于上万个连接。利用Windows平台完成端口进行重叠I/O的技术和Linux在2.6版本的内核中
引入的EPOll技术，可以很方便在在在Windows和Linux平台上开发出支持大量连接的网络服务程序。本文介绍在Windows和Linux平台
上使用的完成端口和EPoll模型开发的基本原理，同时给出实际的例子。本文主要关注C/S结构的服务器端程序，因为一般来说，开发一个大容量，具可扩展
性的winsock程序一般就是指服务程序。<br>
<strong><br>
1、基本概念<br>
</strong>&nbsp;&nbsp;&nbsp;
设备---windows操作系统上允许通信的任何东西，比如文件、目录、串行口、并行口、邮件槽、命名管道、无名管道、套接字、控制台、逻辑磁盘、物理
磁盘等。绝大多数与设备打交道的函数都是CreateFile/ReadFile/WriteFile等。所以我们不能看到**File函数就只想到文件
设备。与设备通信有两种方式，同步方式和异步方式。同步方式下，当调用ReadFile函数时，函数会等待系统执行完所要求的工作，然后才返回；异步方式
下，ReadFile这类函数会直接返回，系统自己去完成对设备的操作，然后以某种方式通知完成操作。<br>
重叠I/O----顾名思义，当你调用了某个函数（比如ReadFile）就立刻返回做自己的其他动作的时候，同时系统也在对I/0设备进行你要求的操
作，在这段时间内你的程序和系统的内部动作是重叠的，因此有更好的性能。所以，重叠I/O是用于异步方式下使用I/O设备的。
重叠I/O需要使用的一个非常重要的数据结构OVERLAPPED。<br>
<strong><br>
2、WINDOWS完成端口的特点<br>
</strong>&nbsp;&nbsp; Win32重叠I/O(Overlapped
I/O)机制允许发起一个操作，然后在操作完成之后接受到信息。对于那种需要很长时间才能完成的操作来说，重叠IO机制尤其有用，因为发起重叠操作的线程
在重叠请求发出后就可以自由的做别的事情了。在WinNT和Win2000上，提供的真正的可扩展的I/O模型就是使用完成端口（Completion
Port）的重叠I/O.完成端口---是一种WINDOWS内核对象。完成端口用于异步方式的重叠I/0情况下，当然重叠I/O不一定非使用完成端口不
可，还有设备内核对象、事件对象、告警I/0等。但是完成端口内部提供了线程池的管理，可以避免反复创建线程的开销，同时可以根据CPU的个数灵活的决定
线程个数，而且可以让减少线程调度的次数从而提高性能其实类似于WSAAsyncSelect和select函数的机制更容易兼容Unix，但是难以实现
我们想要的&#8220;扩展性&#8221;。而且windows的完成端口机制在操作系统内部已经作了优化，提供了更高的效率。所以，我们选择完成端口开始我们的服务器程序的
开发。<br>
1、发起操作不一定完成，系统会在完成的时候通知你，通过用户在完成端口上的等待，处理操作的结果。所以要有检查完成端口，取操作结果的线程。在完成端口
上守候的线程系统有优化，除非在执行的线程阻塞，不会有新的线程被激活，以此来减少线程切换造成的性能代价。所以如果程序中没有太多的阻塞操作，没有必要
启动太多的线程，CPU数量的两倍，一般这样来启动线程。<br>
2、操作与相关数据的绑定方式：在提交数据的时候用户对数据打相应的标记，记录操作的类型，在用户处理操作结果的时候，通过检查自己打的标记和系统的操作结果进行相应的处理。 <br>
3、操作返回的方式:一般操作完成后要通知程序进行后续处理。但写操作可以不通知用户，此时如果用户写操作不能马上完成，写操作的相关数据会被暂存到到非
交换缓冲区中，在操作完成的时候，系统会自动释放缓冲区。此时发起完写操作，使用的内存就可以释放了。此时如果占用非交换缓冲太多会使系统停止响应。<br>
<strong><br>
3、完成端口（Completion Ports ）相关数据结构和创建<br>
</strong>&nbsp;&nbsp;&nbsp; 其实可以把完成端口看成系统维护的一个队列，操作系统把重叠IO操作完成的事件通知放到该队列里，由于是暴露
&#8220;操作完成&#8221;的事件通知，所以命名为&#8220;完成端口&#8221;（COmpletion
Ports）。一个socket被创建后，可以在任何时刻和一个完成端口联系起来。<br>
完成端口相关最重要的是OVERLAPPED数据结构<br>
typedef struct _OVERLAPPED { <br>
&nbsp;&nbsp;&nbsp;   ULONG_PTR Internal;//被系统内部赋值，用来表示系统状态 <br>
&nbsp;&nbsp;&nbsp;   ULONG_PTR InternalHigh;// 被系统内部赋值，传输的字节数 <br>
&nbsp;&nbsp;&nbsp;   union { <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   struct { <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   DWORD Offset;//和OffsetHigh合成一个64位的整数，用来表示从文件头部的多少字节开始 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   DWORD OffsetHigh;//操作，如果不是对文件I/O来操作，则必须设定为0 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   }; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   PVOID Pointer; <br>
&nbsp;&nbsp;&nbsp;   }; <br>
&nbsp;&nbsp;&nbsp;   HANDLE hEvent;//如果不使用，就务必设为0,否则请赋一个有效的Event句柄 <br>
} OVERLAPPED, *LPOVERLAPPED; <br>
<br>
下面是异步方式使用ReadFile的一个例子 <br>
OVERLAPPED Overlapped; <br>
Overlapped.Offset=345; <br>
Overlapped.OffsetHigh=0; <br>
Overlapped.hEvent=0; <br>
//假定其他参数都已经被初始化 <br>
ReadFile(hFile,buffer,sizeof(buffer),&amp;dwNumBytesRead,&amp;Overlapped); <br>
这样就完成了异步方式读文件的操作，然后ReadFile函数返回，由操作系统做自己的事情，下面介绍几个与OVERLAPPED结构相关的函数 <br>
等待重叠I/0操作完成的函数 <br>
BOOL GetOverlappedResult (<br>
HANDLE hFile,<br>
LPOVERLAPPED lpOverlapped,//接受返回的重叠I/0结构<br>
LPDWORD lpcbTransfer,//成功传输了多少字节数<br>
BOOL fWait //TRUE只有当操作完成才返回，FALSE直接返回，如果操作没有完成，通过调//用GetLastError ( )函数会返回ERROR_IO_INCOMPLETE <br>
);<br>
宏HasOverlappedIoCompleted可以帮助我们测试重叠I/0操作是否完成，该宏对OVERLAPPED结构的Internal成员进行了测试，查看是否等于STATUS_PENDING值。</p>
<p style="font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
一般来说，一个应用程序可以创建多个工作线程来处理完成端口上的通知事件。工作线程的数量依赖于程序的具体需要。但是在理想的情况下，应该对应一个CPU
创建一个线程。因为在完成端口理想模型中，每个线程都可以从系统获得一个&#8220;原子&#8221;性的时间片，轮番运行并检查完成端口，线程的切换是额外的开销。在实际开
发的时候，还要考虑这些线程是否牵涉到其他堵塞操作的情况。如果某线程进行堵塞操作，系统则将其挂起，让别的线程获得运行时间。因此，如果有这样的情况，
可以多创建几个线程来尽量利用时间。<br>
应用完成端口：<br>
&nbsp;&nbsp;&nbsp;   创建完成端口：完成端口是一个内核对象，使用时他总是要和至少一个有效的设备句柄进行关联，完成端口是一个复杂的内核对象，创建它的函数是：<br>
HANDLE CreateIoCompletionPort( <br>
&nbsp;&nbsp;&nbsp;   IN HANDLE FileHandle, <br>
&nbsp;&nbsp;&nbsp;   IN HANDLE ExistingCompletionPort, <br>
&nbsp;&nbsp;&nbsp;   IN ULONG_PTR CompletionKey, <br>
&nbsp;&nbsp;&nbsp;   IN DWORD NumberOfConcurrentThreads <br>
&nbsp;&nbsp;&nbsp;   ); <br>
<br>
通常创建工作分两步：<br>
第一步，创建一个新的完成端口内核对象，可以使用下面的函数：<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   HANDLE CreateNewCompletionPort(DWORD dwNumberOfThreads) <br>
{ <br>
&nbsp;&nbsp;&nbsp;&nbsp;   &nbsp;&nbsp;&nbsp;&nbsp;   return CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,NULL,dwNumberOfThreads); <br>
};<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   <br>
第二步，将刚创建的完成端口和一个有效的设备句柄关联起来，可以使用下面的函数：<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   bool AssicoateDeviceWithCompletionPort(HANDLE hCompPort,HANDLE hDevice,DWORD dwCompKey) <br>
{ <br>
&nbsp;&nbsp;&nbsp;&nbsp;   &nbsp;&nbsp;&nbsp;&nbsp;   HANDLE h=CreateIoCompletionPort(hDevice,hCompPort,dwCompKey,0); <br>
&nbsp;&nbsp;&nbsp;&nbsp;   &nbsp;&nbsp;&nbsp;&nbsp;   return h==hCompPort; <br>
}; <br>
说明 <br>
1） CreateIoCompletionPort函数也可以一次性的既创建完成端口对象，又关联到一个有效的设备句柄 <br>
2） CompletionKey是一个可以自己定义的参数，我们可以把一个结构的地址赋给它，然后在合适的时候取出来使用，最好要保证结构里面的内存不是分配在栈上，除非你有十分的把握内存会保留到你要使用的那一刻。<br>
3）
NumberOfConcurrentThreads通常用来指定要允许同时运行的的线程的最大个数。通常我们指定为0，这样系统会根据CPU的个数来自
动确定。创建和关联的动作完成后，系统会将完成端口关联的设备句柄、完成键作为一条纪录加入到这个完成端口的设备列表中。如果你有多个完成端口，就会有多
个对应的设备列表。如果设备句柄被关闭，则表中自动删除该纪录。<br>
<strong><br>
4、完成端口线程的工作原理</strong><br>
完成端口可以帮助我们管理线程池，但是线程池中的线程需要我们使用_beginthreadex来创建，凭什么通知完成端口管理我们的新线程呢？答案在函数GetQueuedCompletionStatus。该函数原型： <br>
BOOL GetQueuedCompletionStatus( <br>
&nbsp;&nbsp;&nbsp;   IN HANDLE CompletionPort, <br>
&nbsp;&nbsp;&nbsp;   OUT LPDWORD lpNumberOfBytesTransferred, <br>
&nbsp;&nbsp;&nbsp;   OUT PULONG_PTR lpCompletionKey, <br>
&nbsp;&nbsp;&nbsp;   OUT LPOVERLAPPED *lpOverlapped, <br>
&nbsp;&nbsp;&nbsp;   IN DWORD dwMilliseconds <br>
); <br>
这个函数试图从指定的完成端口的I/0完成队列中抽取纪录。只有当重叠I/O动作完成的时候，完成队列中才有纪录。凡是调用这个函数的线程将被放入到完成
端口的等待线程队列中，因此完成端口就可以在自己的线程池中帮助我们维护这个线程。完成端口的I/0完成队列中存放了当重叠I/0完成的结果----
一条纪录，该纪录拥有四个字段，前三项就对应GetQueuedCompletionStatus函数的2、3、4参数，最后一个字段是错误信息
dwError。我们也可以通过调用PostQueudCompletionStatus模拟完成了一个重叠I/0操作。 <br>
当I/0完成队列中出现了纪录，完成端口将会检查等待线程队列，该队列中的线程都是通过调用GetQueuedCompletionStatus函数使自
己加入队列的。等待线程队列很简单，只是保存了这些线程的ID。完成端口会按照后进先出的原则将一个线程队列的ID放入到释放线程列表中，同时该线程将从
等待GetQueuedCompletionStatus函数返回的睡眠状态中变为可调度状态等待CPU的调度。所以我们的线程要想成为完成端口管理的线
程，就必须要调用GetQueuedCompletionStatus函数。出于性能的优化，实际上完成端口还维护了一个暂停线程列表，具体细节可以参考
《Windows高级编程指南》，我们现在知道的知识，已经足够了。
完成端口线程间数据传递线程间传递数据最常用的办法是在_beginthreadex函数中将参数传递给线程函数，或者使用全局变量。但是完成端口还有自
己的传递数据的方法，答案就在于CompletionKey和OVERLAPPED参数。<br>
CompletionKey被保存在完成端口的设备表中，是和设备句柄一一对应的，我们可以将与设备句柄相关的数据保存到CompletionKey中，
或者将CompletionKey表示为结构指针，这样就可以传递更加丰富的内容。这些内容只能在一开始关联完成端口和设备句柄的时候做，因此不能在以后
动态改变。<br>
OVERLAPPED参数是在每次调用ReadFile这样的支持重叠I/0的函数时传递给完成端口的。我们可以看到，如果我们不是对文件设备做操作，该
结构的成员变量就对我们几乎毫无作用。我们需要附加信息，可以创建自己的结构，然后将OVERLAPPED结构变量作为我们结构变量的第一个成员，然后传
递第一个成员变量的地址给ReadFile函数。因为类型匹配，当然可以通过编译。当GetQueuedCompletionStatus函数返回时，我
们可以获取到第一个成员变量的地址，然后一个简单的强制转换，我们就可以把它当作完整的自定义结构的指针使用，这样就可以传递很多附加的数据了。太好了！
只有一点要注意，如果跨线程传递，请注意将数据分配到堆上，并且接收端应该将数据用完后释放。我们通常需要将ReadFile这样的异步函数的所需要的缓
冲区放到我们自定义的结构中，这样当GetQueuedCompletionStatus被返回时，我们的自定义结构的缓冲区变量中就存放了I/0操作的
数据。CompletionKey和OVERLAPPED参数，都可以通过GetQueuedCompletionStatus函数获得。<br>
线程的安全退出<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   很多线程为了不止一次的执行异步数据处理，需要使用如下语句<br>
while (true)<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   ......<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   GetQueuedCompletionStatus(...); <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   ......<br>
}<br>
那么如何退出呢，答案就在于上面曾提到的PostQueudCompletionStatus函数，我们可以用它发送一个自定义的包含了OVERLAPPED成员变量的结构地址，里面包含一个状态变量，当状态变量为退出标志时，线程就执行清除动作然后退出。<br>
<strong><br>
5、Windows完成端口的实例代码：<br>
</strong>DWORD WINAPI WorkerThread(LPVOID lpParam)<br>
{ <br>
ULONG_PTR *PerHandleKey;<br>
OVERLAPPED *Overlap;<br>
OVERLAPPEDPLUS *OverlapPlus,<br>
*newolp;<br>
DWORD dwBytesXfered;<br>
while (1)<br>
{<br>
ret = GetQueuedCompletionStatus(<br>
hIocp,<br>
&amp;dwBytesXfered,<br>
(PULONG_PTR)&amp;PerHandleKey,<br>
&amp;Overlap,<br>
INFINITE);<br>
if (ret == 0)<br>
{<br>
// Operation failed<br>
continue;<br>
}<br>
OverlapPlus = CONTAINING_RECORD(Overlap, OVERLAPPEDPLUS, ol);<br>
switch (OverlapPlus-&gt;OpCode)<br>
{<br>
case OP_ACCEPT:<br>
// Client socket is contained in OverlapPlus.sclient<br>
// Add client to completion port<br>
CreateIoCompletionPort(<br>
(HANDLE)OverlapPlus-&gt;sclient,<br>
hIocp,<br>
(ULONG_PTR)0,<br>
0);<br>
// Need a new OVERLAPPEDPLUS structure<br>
// for the newly accepted socket. Perhaps<br>
// keep a look aside list of free structures.<br>
newolp = AllocateOverlappedPlus();<br>
if (!newolp)<br>
{<br>
// Error<br>
}<br>
newolp-&gt;s = OverlapPlus-&gt;sclient;<br>
newolp-&gt;OpCode = OP_READ;<br>
// This function divpares the data to be sent<br>
PrepareSendBuffer(&amp;newolp-&gt;wbuf);<br>
ret = WSASend(<br>
newolp-&gt;s,<br>
&amp;newolp-&gt;wbuf,<br>
1,<br>
&amp;newolp-&gt;dwBytes,<br>
0,<br>
&amp;newolp.ol,<br>
NULL);<br>
if (ret == SOCKET_ERROR)<br>
{<br>
if (WSAGetLastError() != WSA_IO_PENDING)<br>
{<br>
// Error<br>
}<br>
}<br>
// Put structure in look aside list for later use<br>
FreeOverlappedPlus(OverlapPlus);<br>
// Signal accept thread to issue another AcceptEx<br>
SetEvent(hAcceptThread);<br>
break;<br>
case OP_READ:<br>
// Process the data read <br>
// Repost the read if necessary, reusing the same<br>
// receive buffer as before<br>
memset(&amp;OverlapPlus-&gt;ol, 0, sizeof(OVERLAPPED));<br>
ret = WSARecv(<br>
OverlapPlus-&gt;s,<br>
&amp;OverlapPlus-&gt;wbuf,<br>
1,<br>
&amp;OverlapPlus-&gt;dwBytes,<br>
&amp;OverlapPlus-&gt;dwFlags,<br>
&amp;OverlapPlus-&gt;ol,<br>
NULL);<br>
if (ret == SOCKET_ERROR)<br>
{<br>
if (WSAGetLastError() != WSA_IO_PENDING)<br>
{<br>
// Error<br>
}<br>
}<br>
break;<br>
case OP_WRITE:<br>
// Process the data sent, etc.<br>
break;<br>
} // switch<br>
} // while<br>
} // WorkerThread<br>
</p>
<p style="font-family: courier new;">查看以上代码，注意如果Overlapped操作立刻失败（比如，返回SOCKET_ERROR或其他非WSA_IO_PENDING的错误），则
没有任何完成通知时间会被放到完成端口队列里。反之，则一定有相应的通知时间被放到完成端口队列。更完善的关于Winsock的完成端口机制，可以参考
MSDN的Microsoft PlatFormSDK，那里有完成端口的例子。访问<a  href="http://msdn.microsoft.com/library/techart/msdn_servrapp.htm" target="_blank">http://msdn.microsoft.com/library/techart/msdn_servrapp.htm</a>可以获得更多信息。</p>
<p style="font-family: courier new;"><strong>Linux的EPoll模型<br>
</strong>Linux 2.6内核中提高网络I/O性能的新方法-epoll I/O多路复用技术在比较多的TCP网络服务器中有使用，即比较多的用到select函数。<br>
<br>
<strong>1、为什么select落后<br>
</strong>首先，在Linux内核中，select所用到的FD_SET是有限的，即内核中有个参数__FD_SETSIZE定义了每个FD_SET的句柄个数，在我用的2.6.15-25-386内核中，该值是1024，搜索内核源代码得到：<br>
include/linux/posix_types.h:#define __FD_SETSIZE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   1024<br>
也就是说，如果想要同时检测1025个句柄的可读状态是不可能用select实现的。或者同时检测1025个句柄的可写状态也是不可能的。其次，内核中实
现select是用轮询方法，即每次检测都会遍历所有FD_SET中的句柄，显然，select函数执行时间与FD_SET中的句柄个数有一个比例关系，
即select要检测的句柄数越多就会越费时。当然，在前文中我并没有提及poll方法，事实上用select的朋友一定也试过poll，我个人觉得
select和poll大同小异，个人偏好于用select而已。</p>
<p style="font-family: courier new;"><strong>2、内核中提高I/O性能的新方法epoll</strong><br>
epoll是什么？按照man手册的说法：是为处理大批量句柄而作了改进的poll。要使用epoll只需要这三个系统调用：epoll_create(2)， epoll_ctl(2)， epoll_wait(2)。<br>
当然，这不是2.6内核才有的，它是在2.5.44内核中被引进的(epoll(4) is a new API introduced in Linux kernel 2.5.44)</p>
<p style="font-family: courier new;">Linux2.6内核epoll介绍<br>
先介绍2本书《The Linux Networking Architecture--Design and Implementation of
Network Protocols in the Linux Kernel》，以2.4内核讲解Linux
TCP/IP实现，相当不错.作为一个现实世界中的实现，很多时候你必须作很多权衡，这时候参考一个久经考验的系统更有实际意义。举个例子,linux内
核中sk_buff结构为了追求速度和安全，牺牲了部分内存，所以在发送TCP包的时候，无论应用层数据多大,sk_buff最小也有272的字节.其实
对于socket应用层程序来说，另外一本书《UNIX Network Programming Volume
1》意义更大一点.2003年的时候，这本书出了最新的第3版本，不过主要还是修订第2版本。其中第6章《I/O
Multiplexing》是最重要的。Stevens给出了网络IO的基本模型。在这里最重要的莫过于select模型和Asynchronous
I/O模型.从理论上说，AIO似乎是最高效的，你的IO操作可以立即返回，然后等待os告诉你IO操作完成。但是一直以来，如何实现就没有一个完美的方
案。最著名的windows完成端口实现的AIO,实际上也是内部用线程池实现的罢了，最后的结果是IO有个线程池，你应用也需要一个线程池......
很多文档其实已经指出了这带来的线程context-switch带来的代价。在linux
平台上，关于网络AIO一直是改动最多的地方，2.4的年代就有很多AIO内核patch,最著名的应该算是SGI那个。但是一直到2.6内核发布，网络
模块的AIO一直没有进入稳定内核版本(大部分都是使用用户线程模拟方法，在使用了NPTL的linux上面其实和windows的完成端口基本上差不多
了)。2.6内核所支持的AIO特指磁盘的AIO---支持io_submit(),io_getevents()以及对Direct
IO的支持(就是绕过VFS系统buffer直接写硬盘，对于流服务器在内存平稳性上有相当帮助)。<br>
所以，剩下的select模型基本上就是我们在linux上面的唯一选择，其实，如果加上no-block
socket的配置，可以完成一个"伪"AIO的实现，只不过推动力在于你而不是os而已。不过传统的select/poll函数有着一些无法忍受的缺
点，所以改进一直是2.4-2.5开发版本内核的任务，包括/dev/poll，realtime signal等等。最终，Davide
Libenzi开发的epoll进入2.6内核成为正式的解决方案<br>
<strong><br>
3、epoll的优点</strong><br>
&lt;1&gt;支持一个进程打开大数目的socket描述符(FD)<br>
select
最不能忍受的是一个进程所打开的FD是有一定限制的，由FD_SETSIZE设置，默认值是2048。对于那些需要支持的上万连接数目的IM服务器来说显
然太少了。这时候你一是可以选择修改这个宏然后重新编译内核，不过资料也同时指出这样会带来网络效率的下降，二是可以选择多进程的解决方案(传统的
Apache方案)，不过虽然linux上面创建进程的代价比较小，但仍旧是不可忽视的，加上进程间数据同步远比不上线程间同步的高效，所以也不是一种完
美的方案。不过
epoll则没有这个限制，它所支持的FD上限是最大可以打开文件的数目，这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左
右，具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。<br>
&lt;2&gt;IO效率不随FD数目增加而线性下降<br>
传统的select/poll另一个致命弱点就是当你拥有一个很大的socket集合，不过由于网络延时，任一时间只有部分的socket是"活跃"的，
但是select/poll每次调用都会线性扫描全部的集合，导致效率呈现线性下降。但是epoll不存在这个问题，它只会对"活跃"的socket进行
操作---这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的。那么，只有"活跃"的socket才会主动的去调用
callback函数，其他idle状态socket则不会，在这点上，epoll实现了一个"伪"AIO，因为这时候推动力在os内核。在一些
benchmark中，如果所有的socket基本上都是活跃的---比如一个高速LAN环境，epoll并不比select/poll有什么效率，相
反，如果过多使用epoll_ctl,效率相比还有稍微的下降。但是一旦使用idle
connections模拟WAN环境,epoll的效率就远在select/poll之上了。<br>
&lt;3&gt;使用mmap加速内核与用户空间的消息传递。<br>
这点实际上涉及到epoll的具体实现了。无论是select,poll还是epoll都需要内核把FD消息通知给用户空间，如何避免不必要的内存拷贝就
很重要，在这点上，epoll是通过内核于用户空间mmap同一块内存实现的。而如果你想我一样从2.5内核就关注epoll的话，一定不会忘记手工
mmap这一步的。<br>
&lt;4&gt;内核微调<br>
这一点其实不算epoll的优点了，而是整个linux平台的优点。也许你可以怀疑linux平台，但是你无法回避linux平台赋予你微调内核的能力。
比如，内核TCP/IP协议栈使用内存池管理sk_buff结构，那么可以在运行时期动态调整这个内存pool(skb_head_pool)的大小--
- 通过echo
XXXX&gt;/proc/sys/net/core/hot_list_length完成。再比如listen函数的第2个参数(TCP完成3次握手
的数据包队列长度)，也可以根据你平台内存大小动态调整。更甚至在一个数据包面数目巨大但同时每个数据包本身大小却很小的特殊系统上尝试最新的NAPI网
卡驱动架构。<br>
4、epoll的工作模式<br>
令人高兴的是，2.6内核的epoll比其2.5开发版本的/dev/epoll简洁了许多，所以，大部分情况下，强大的东西往往是简单的。唯一有点麻烦是epoll有2种工作方式:LT和ET。<br>
LT(level triggered)是缺省的工作方式，并且同时支持block和no-block
socket.在这种做法中，内核告诉你一个文件描述符是否就绪了，然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作，内核还是会继续通知你
的，所以，这种模式编程出错误可能性要小一点。传统的select/poll都是这种模型的代表．<br>
ET (edge-triggered)是高速工作方式，只支持no-block
socket。在这种模式下，当描述符从未就绪变为就绪时，内核通过epoll告诉你。然后它会假设你知道文件描述符已经就绪，并且不会再为那个文件描述
符发送更多的就绪通知，直到你做了某些操作导致那个文件描述符不再为就绪状态了(比如，你在发送，接收或者接收请求，或者发送接收的数据少于一定量时导致
了一个EWOULDBLOCK 错误）。但是请注意，如果一直不对这个fd作IO操作(从而导致它再次变成未就绪)，内核不会发送更多的通知(only
once),不过在TCP协议中，ET模式的加速效用仍需要更多的benchmark确认。<br>
epoll只有epoll_create,epoll_ctl,epoll_wait 3个系统调用，具体用法请参考<a  href="http://www.xmailserver.org/linux-patches/nio-improve.html" target="_blank">http://www.xmailserver.org/linux-patches/nio-improve.html</a> ，在<a  href="http://www.kegel.com/rn/" target="_blank">http://www.kegel.com/rn/</a>也有一个完整的例子，大家一看就知道如何使用了<br>
Leader/follower模式线程pool实现，以及和epoll的配合。<br>
<br>
<strong>5、 epoll的使用方法</strong><br>
&nbsp;&nbsp;&nbsp; 首先通过create_epoll(int
maxfds)来创建一个epoll的句柄，其中maxfds为你epoll所支持的最大句柄数。这个函数会返回一个新的epoll句柄，之后的所有操作
将通过这个句柄来进行操作。在用完之后，记得用close()来关闭这个创建出来的epoll句柄。
之后在你的网络主循环里面，每一帧的调用epoll_wait(int epfd, epoll_event events, int max
events, int timeout)来查询所有的网络接口，看哪一个可以读，哪一个可以写了。基本的语法为： <br>
nfds = epoll_wait(kdpfd, events, maxevents, -1); <br>
其中kdpfd为用epoll_create创建之后的句柄，events是一个epoll_event*的指针，当epoll_wait这个函数操作成
功之后，epoll_events里面将储存所有的读写事件。max_events是当前需要监听的所有socket句柄数。最后一个timeout是
epoll_wait的超时，为0的时候表示马上返回，为-1的时候表示一直等下去，直到有事件范围，为任意正整数的时候表示等这么长的时间，如果一直没
有事件，则范围。一般如果网络主循环是单独的线程的话，可以用-1来等，这样可以保证一些效率，如果是和主逻辑在同一个线程的话，则可以用0来保证主循环
的效率。</p>
<p style="font-family: courier new;">epoll_wait范围之后应该是一个循环，遍利所有的事件： <br>
for(n = 0; n &lt; nfds; ++n) { <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   if(events[n].data.fd == listener) { //如果是主socket的事件的话，则表示有新连接进入了，进行新连接的处理。 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   client = accept(listener, (struct sockaddr *) &amp;local, <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   &amp;addrlen); <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   if(client &lt; 0){ <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   perror("accept"); <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   continue; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   } <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   setnonblocking(client); // 将新连接置于非阻塞模式 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   ev.events = EPOLLIN | EPOLLET; // 并且将新连接也加入EPOLL的监听队列。 <br>
注意，这里的参数EPOLLIN | EPOLLET并没有设置对写socket的监听，如果有写操作的话，这个时候epoll是不会返回事件的，如果要对写操作也监听的话，应该是EPOLLIN | EPOLLOUT | EPOLLET <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   ev.data.fd = client; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, client, &amp;ev) &lt; 0) { <br>
//
设置好event之后，将这个新的event通过epoll_ctl加入到epoll的监听队列里面，这里用EPOLL_CTL_ADD来加一个新的
epoll事件，通过EPOLL_CTL_DEL来减少一个epoll事件，通过EPOLL_CTL_MOD来改变一个事件的监听方式。 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   fprintf(stderr, "epoll set insertion error: fd=%d0, <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   client); <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   return -1; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   } <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   } <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   else // 如果不是主socket的事件的话，则代表是一个用户socket的事件，则来处理这个用户socket的事情，比如说read(fd,xxx)之类的，或者一些其他的处理。 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   do_use_fd(events[n].data.fd); <br>
}</p>
<p style="font-family: courier new;">对，epoll的操作就这么简单，总共不过4个API：epoll_create, epoll_ctl, epoll_wait和close。 <br>
如果您对epoll的效率还不太了解，请参考我之前关于网络游戏的网络编程等相关的文章。</p>
<p style="font-family: courier new;"><br>
以前公司的服务器都是使用HTTP连接，但是这样的话，在手机目前的网络情况下不但显得速度较慢，而且不稳定。因此大家一致同意用SOCKET来进行连
接。虽然使用SOCKET之后，对于用户的费用可能会增加(由于是用了CMNET而非CMWAP)，但是，秉着用户体验至上的原则，相信大家还是能够接受
的(希望那些玩家月末收到帐单不后能够保持克制...)。<br>
这次的服务器设计中，最重要的一个突破，是使用了EPOLL模型，虽然对之也是一知半解，但是既然在各大PC网游中已经经过了如此严酷的考验，相信他不会让我们失望，使用后的结果，确实也是表现相当不错。在这里，我还是主要大致介绍一下这个模型的结构。<br>
6、Linux下EPOll编程实例<br>
EPOLL模型似乎只有一种格式，所以大家只要参考我下面的代码，就能够对EPOLL有所了解了，代码的解释都已经在注释中：</p>
<p style="font-family: courier new;">while (TRUE)<br>
{<br>
int nfds = epoll_wait (m_epoll_fd, m_events, MAX_EVENTS, EPOLL_TIME_OUT);//等待EPOLL时间的发生，相当于监听，至于相关的端口，需要在初始化EPOLL的时候绑定。<br>
if (nfds &lt;= 0)<br>
continue;<br>
m_bOnTimeChecking = FALSE;<br>
G_CurTime = time(NULL);<br>
for (int i=0; i<br>
{<br>
try<br>
{<br>
if (m_events.data.fd == m_listen_http_fd)//如果新监测到一个HTTP用户连接到绑定的HTTP端口，建立新的连接。由于我们新采用了SOCKET连接，所以基本没用。<br>
{<br>
OnAcceptHttpEpoll ();<br>
}<br>
else if (m_events.data.fd == m_listen_sock_fd)//如果新监测到一个SOCKET用户连接到了绑定的SOCKET端口，建立新的连接。<br>
{<br>
OnAcceptSockEpoll ();<br>
}<br>
else if (m_events.events &amp; EPOLLIN)//如果是已经连接的用户，并且收到数据，那么进行读入。<br>
{<br>
OnReadEpoll (i);<br>
}</p>
<p style="font-family: courier new;">OnWriteEpoll (i);//查看当前的活动连接是否有需要写出的数据。<br>
}<br>
catch (int)<br>
{<br>
PRINTF ("CATCH捕获错误\n");<br>
continue;<br>
}<br>
}<br>
m_bOnTimeChecking = TRUE;<br>
OnTimer ();//进行一些定时的操作，主要就是删除一些短线用户等。<br>
}<br>
其实EPOLL的精华，也就是上述的几段短短的代码，看来时代真的不同了，以前如何接受大量用户连接的问题，现在却被如此轻松的搞定，真是让人不得不感叹，对哪。</p>
<br style="font-family: courier new;">
<strong style="font-family: courier new;">总结<br>
</strong><span style="font-family: courier new;">Windows完成端口与Linux epoll技术方案是这2个平台上实现异步IO和设计开发一个大容量，具可扩展性的winsock程序指服务程序的很好的选择，本文对这2中技术的实现原理和实际的使用方法做了一个详细的介绍</span></span><img src ="http://www.cppblog.com/guojingjia2006/aggbug/124945.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2010-08-27 15:43 <a href="http://www.cppblog.com/guojingjia2006/archive/2010/08/27/124945.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux 系统查用命令集</title><link>http://www.cppblog.com/guojingjia2006/archive/2010/08/19/123926.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Thu, 19 Aug 2010 01:50:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2010/08/19/123926.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/123926.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2010/08/19/123926.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/123926.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/123926.html</trackback:ping><description><![CDATA[<pre>http://www.pixelbeat.org/cmdline_zh_CN.html<br><br># uname -a               # 查看内核/操作系统/CPU信息<br># head -n 1 /etc/issue   # 查看操作系统版本<br># cat /proc/cpuinfo      # 查看CPU信息<br># hostname               # 查看计算机名<br># lspci -tv              # 列出所有PCI设备<br># lsusb -tv              # 列出所有USB设备<br># lsmod                  # 列出加载的内核模块<br># env                    # 查看环境变量<br><br># free -m                # 查看内存使用量和交换区使用量<br># df -h                  # 查看各分区使用情况<br># du -sh &lt;目录名&gt;        # 查看指定目录的大小<br># grep MemTotal /proc/meminfo   # 查看内存总量<br># grep MemFree /proc/meminfo    # 查看空闲内存量<br># uptime                 # 查看系统运行时间、用户数、负载<br># cat /proc/loadavg      # 查看系统负载<br><br># mount | column -t      # 查看挂接的分区状态<br># fdisk -l               # 查看所有分区<br># swapon -s              # 查看所有交换分区<br># hdparm -i /dev/hda     # 查看磁盘参数(仅适用于IDE设备)<br># dmesg | grep IDE       # 查看启动时IDE设备检测状况<br><br># ifconfig               # 查看所有网络接口的属性<br># iptables -L            # 查看防火墙设置<br># route -n               # 查看路由表<br># netstat -lntp          # 查看所有监听端口<br># netstat -antp          # 查看所有已经建立的连接<br># netstat -s             # 查看网络统计信息<br><br># ps -ef                 # 查看所有进程<br># top                    # 实时显示进程状态<br><br># w                      # 查看活动用户<br># id &lt;用户名&gt;            # 查看指定用户信息<br># last                   # 查看用户登录日志<br># cut -d: -f1 /etc/passwd   # 查看系统所有用户<br># cut -d: -f1 /etc/group    # 查看系统所有组<br># crontab -l             # 查看当前用户的计划任务<br><br># chkconfig --list       # 列出所有系统服务<br># chkconfig --list | grep on    # 列出所有启动的系统服务<br></pre><img src ="http://www.cppblog.com/guojingjia2006/aggbug/123926.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2010-08-19 09:50 <a href="http://www.cppblog.com/guojingjia2006/archive/2010/08/19/123926.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux 内核编译</title><link>http://www.cppblog.com/guojingjia2006/archive/2010/08/12/123236.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Thu, 12 Aug 2010 10:46:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2010/08/12/123236.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/123236.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2010/08/12/123236.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/123236.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/123236.html</trackback:ping><description><![CDATA[1.错误提示缺包：<font color="#00ff00">libncurses5-dev<br>2.</font>如果以前编译过，现执行make mrproper清理<br>3.make menuconfig&nbsp; | make xconfig | make config| make oldconfig(已经存在.config)<br>(可以修改makefile,携带自己信息,编译出来的内核,修改以后原来的模块要重新编译)<br>4.make dep(建立模块依赖)<br><br>(.config可以从/boot/config-xxx copy过来，可以先试下)<br>make<br>make modules<br>make modules_install<br>make install<br>////////////////////////////////////////<br>具体错误提示见最后面<br>
<br>
1.make menuconfig<br>
解决方法：sudo apt-get install libncurses5-dev（ubuntu）其他的发行版找到对应的包就好<br>
2.make xconfig<br>
解决办法 ：sudo apt-get install libqt3-mt-dev <br>
3. make gconfig<br>
解决办法： apt-get install libglade2-dev<br>   <img src ="http://www.cppblog.com/guojingjia2006/aggbug/123236.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2010-08-12 18:46 <a href="http://www.cppblog.com/guojingjia2006/archive/2010/08/12/123236.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>tq2440板子上的第一个运行程序</title><link>http://www.cppblog.com/guojingjia2006/archive/2010/08/11/123055.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Wed, 11 Aug 2010 05:03:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2010/08/11/123055.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/123055.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2010/08/11/123055.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/123055.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/123055.html</trackback:ping><description><![CDATA[拿到板子3天了，之间看了tq2440的使用手册，和linux下的编译视频,感觉挺好的，于是开始了自己的第一个arm板上的程序,聊天程序<br><br>运行效果：<br><img alt=""  src="http://www.cppblog.com/images/cppblog_com/guojingjia2006/arm.jpg" height="460" width="819"><br><br>左边是tq2440板子的终端，右边是win7下的控制台，arm上的linux作为服务器，win7客户端.自己前几天写的一个windows-linux跨平台的socket终于跑起来了。:)<br><br>下面说下自己从搭建到运行的整个流程：<br>1.先跑裸机程序吧，我就跑了那个test的，nor flash模式下直接把tq2440_test.bin烧写进去，那个bin我没找到，所以自己编译了。裸机程序玩完后，就可以玩linux或wince了。<br>2.完后烧写linux系统，因为tq光盘里附带了embedSky的编译完整的linux bin.所以推荐先用这个，按使用手册来做,烧写在nor模式下进行，完成后，切换到nand 模式，进入系统。<br>3.之后，我不知道怎么在板子的linux上跑自己的程序，完了我看了光盘的linux资源下的linux编译视频，推荐先看这几个，他教你怎么在linux上编译uboot,内核==,编译出来的当然在板子上运行的，所以首先你的搭建好交叉编译环境,embedSky 附带了一个交叉编译器的，可以直接用他的，在linux移植手册中有介绍编译自己的交叉编译器的，先用这个吧。编译好后，配置完系统环境变量，就有了arm-linux-gcc,arm-linux-g++了。<br>4.eclipse下配置编译选项，在项目属性里将gcc,g++,link的command前面加上arm-linux,这样编译出来的程序就能在arm上跑了。<br>5.编译完后，怎么弄到板子上呢。我也比较困惑，因为自己也没弄过，所以还得看手册，现在我知道有两种方式可以，第一个就是开发板上有usb的接口，你将自己编译完的程序弄到usb里，完了将usb挂载到linux的某个目录下，拷贝到运行目录就行了，tq2440的默认的目录是在/sbin下的，第二种就是用nfs方式，先在pc linux端装nfs服务，完了可以用网络方式将pc端的nfs设立的共享文件夹挂载到板子上的linux。之后就可以直接运行了。<br><br>上面就是自己的从完全不懂得到能跑自己的程序的一个流程。努力，继续自己的嵌入式之旅。<br><br><br><img src ="http://www.cppblog.com/guojingjia2006/aggbug/123055.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2010-08-11 13:03 <a href="http://www.cppblog.com/guojingjia2006/archive/2010/08/11/123055.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>nfs ---  开发板挂载ubuntu 10.04 目录</title><link>http://www.cppblog.com/guojingjia2006/archive/2010/08/11/123031.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Wed, 11 Aug 2010 02:16:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2010/08/11/123031.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/123031.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2010/08/11/123031.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/123031.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/123031.html</trackback:ping><description><![CDATA[<div id="content">
<p>1&nbsp; NFS安装</p>
<p>nfs原理是通过网络，将远程主机共享的文件系统，挂载到本机。<a href="http://www.linuxidc.com/topicnews.aspx?tid=2" title="Ubuntu">Ubuntu</a> 10.04上默认是没有安装NFS服务器的，首先要安装NFS服务程序：</p>
<p>#&nbsp; sudo apt-get install nfs-kernel-server</p>
<p>(安装nfs-kernel-server时，apt会自动安装nfs-common和portmap） 这样，宿主机就相当于NFS Server。<!--iwms_ad_begin--></p>
<table align="center" border="0" width="97%">
    <tbody>
        <tr>
            <td colspan="3">
            <div align="center">
            <script src="http://www.linuxidc.com/system/system60.js" type="text/javascript" language="javaScript"></script>
            </div>
            <br></td>
        </tr>
    </tbody>
</table>
<!--iwms_ad_end-->
<p>2&nbsp;&nbsp; 宿主机NFS的配置</p>
<p>2.1&nbsp; 修改配置文件/etc/exports</p>
<p>在终端下用#&nbsp; vim&nbsp; /etc/exports打开exports文件。</p>
<p>如果你没有配置过这个文件的话此文件应该是空的。在开始部分写入</p>
<p>/home&nbsp;&nbsp; *(rw,sync,no_root_squash)</p>
<p>/home&nbsp; -- 与客户机共享的目录；</p>
<p>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- 表示允许任意用户使用，也可以使用具体IP；</p>
<p>(rw,sync,no_root_squash)&nbsp; -- rw，挂载此目录的客户机对此目录有读写权利；</p>
<p>sync，&#8230;&#8230;；</p>
<p>no_root_squash，挂载此目录的客户机享有主机root的权利；</p>
<p>我是将主机的根目录设置为共享目录&nbsp; /&nbsp; *(rw,sync,no_root_squash)</p>
<p>OK，保存，退出。</p>
<p>修改完成之后输入：#&nbsp; exportfs &#8211;rv来使配置文件生效</p>
<p>2.2&nbsp;&nbsp; 配置宿主机的IP</p>
<p>配置宿主机的IP，在命令行中输入 # ifconfig&nbsp;&nbsp; 来查看本机的IP地址。如果没有设置，可以用命令 # ifconfig eth0
192.168.0.18 来设置IP。其中的IP地址可以根据具体情况来设定。设定完成后在通过ifconfig来再次查看是否已经设定成功。</p>
<p>2.3&nbsp;&nbsp; 启动宿主机NFS服务</p>
<p>安装完NFS服务后就可以通过 #&nbsp; /etc/init.d/nfs-kernel-server
restart（/etc/init.d/nfs-kernel-server
start）来重新开启网络文件系统服务，以便后面的开发板挂载。也可以通过#&nbsp; /etc/init.d/nfs-kernel-server
stop来停止。</p>
<p>3&nbsp;&nbsp; 目标板的挂载操作</p>
<p>给你的目标机上电，目标板上的Linux操作系统起来以后，在PC机上<a href="http://www.linuxidc.com/topicnews.aspx?tid=2" title="Ubuntu">Ubuntu</a>操作系统上打开minicom，通过串口向目标板发送shell命令。</p>
<p>像主机操作一样，首先检查目标板（客户机）的IP是否与宿主机的IP再同一个地址段上，否则用上面用过的命令进行检查和设置本地IP。</p>
<p>设置完IP之后可以ping一下检查网卡、网线是否连接正确。</p>
<p>既在minicom中输入# ping 192.168.0.18&nbsp; （主机IP地址）连接成功会不断的打印信息。</p>
<p>接下来就是在开发板上进行挂载mount</p>
<p><strong><span style="font-size: 100%; color: #ff0000;"><tt><tt class="COMMAND"><font color="#000000"><span style="background-color: #ffffff;">mount -t nfs -o intr,nolock,rsize=1024,wsize=1024 192.168.0.121:/<font color="#ff0000">主机nfs目录</font> /<font color="#ff0000">挂载路径</font></span></font></tt></tt></span></strong></p>
<p><strong><span style="font-size: 100%; color: #ff0000;"><tt><tt class="COMMAND"><font color="#000000"><span style="background-color: #ffffff;"><font color="#ff0000"><br></font></span></font></tt></tt></span></strong></p>
<p>其中：后是客户机挂载的共享目录； /mnt是开发板的挂载目录</p>
<p>OK，挂在完成。</p>
<p>通过</p>
<p># cd&nbsp; /mnt</p>
<p># ls</p>
<p>可以发现主机的根目录被挂载进了开发板mnt目录中。</p>
<p>如果你想取消挂在可以使用命令# umount&nbsp; /mnt就可以了。</p>
<p><br></p>
<p>-------------------------------------------</p>
<p><br></p>
<p>nfs:server is not responding,still trying    原因与解决方案</p>
<p><br></p>
<p><strong><span style="font-size: 100%; color: #ff0000;"><tt><tt class="COMMAND"><font color="#000000"><span style="background-color: #ffffff;">mount -t nfs -o intr,nolock,rsize=1024,wsize=1024 192.168.0.121:/<font color="#ff0000">主机nfs目录</font> /<font color="#ff0000">挂载路径</font></span></font></tt></tt></span></strong></p>
<p><br>
<strong><span style="font-size: 100%; color: #ff0000;"><tt><tt class="COMMAND"><font color="#000000"><span style="background-color: #ffffff;"></span></font></tt></tt></span></strong></p>
<p><strong><span style="font-size: 100%; color: #ff0000;"><tt><tt class="COMMAND"><font color="#000000"><span style="background-color: #ffffff;"><font color="#ff0000">tcp挂载，不然很可能出现服务不响应，nfs默认是udp传输。。（这个把我郁闷了一天）</font></span></font></tt></tt></span></strong></p>
</div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/123031.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2010-08-11 10:16 <a href="http://www.cppblog.com/guojingjia2006/archive/2010/08/11/123031.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ubuntu 10.04 root  登陆 (转)</title><link>http://www.cppblog.com/guojingjia2006/archive/2010/08/10/122944.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Tue, 10 Aug 2010 08:26:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2010/08/10/122944.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/122944.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2010/08/10/122944.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/122944.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/122944.html</trackback:ping><description><![CDATA[<p>安装后，root用户默认是被锁定了的，不允许登录，也不允许&#8220;su&#8221;到
root。有人说这是个不好的实践，特别是对于服务器来说。我觉得对于桌面用户来说，这样安全性更高一些，是应该的；但对于服务器可以设置成&#8220;允许
su 到root，但不允许root用户直接登录&#8221;。而我为了开发时的方便，则在桌面和服务器上都采用这种方式。</p>
<p>允许 su 到 root</p>
<p>非常简单，下面是设置的方法：</p>
<p><a  href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#109;&#101;&#64;&#116;&#105;&#112;&#102;&#111;&#111;&#58;&#37;&#55;&#69;&#36;">me@tipfoo:~$</a> sudo passwd
root</p>
<p>Password: &lt;--- 输入安装时那个用户的密码</p>
<p>Enter new UNIX password: &lt;--- 新的Root用户密码</p>
<p>Retype new UNIX password: &lt;--- 重复新的Root用户密码</p>
<p>passwd：已成功更新密码</p>
<p>允许root登录</p>
<p>如果要允许root登录（不推荐），则这样操作：</p>
<p><a  href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#109;&#101;&#64;&#116;&#105;&#112;&#102;&#111;&#111;&#58;&#37;&#55;&#69;&#36;">me@tipfoo:~$</a> gksu
/usr/sbin/gdmsetup</p>
<p>（或者使用桌面菜单：系统＞系统管理＞登录窗口）</p>
<p>点&#8220;安全&#8221;选项页，选择&#8220;允许本地管理员登录&#8221;。</p>
<p>注：这一步依赖上一步</p>
<p>在登录时直接显示root用户：</p>
<p>在root用户下gedit /etc/gdm/gdm.schemas</p>
<p>&lt;schema&gt;<br>
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;key&gt;greeter/Include&lt;/key&gt;<br>
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;signature&gt;s&lt;/signature&gt;<br>
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;default&gt;&lt;/default&gt;<br>
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;/schema&gt;</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;schema&gt;<br>
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;key&gt;greeter/Exclude&lt;/key&gt;<br>
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;signature&gt;s&lt;/signature&gt;<br>
&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>
&lt;default&gt;bin,root,daemon,adm,lp,sync,shutdown,halt,mail,news,uucp,operator,nobody,nobody4,noaccess,postgres,pvm,rpm,nfsnobody,pcap&lt;/default&gt;<br>
&nbsp;<wbr>&nbsp;<wbr>
&lt;/schema&gt;</p>
<p>把下边schema中的root去掉，放到上面的那个里面，可以在登陆框里看到root了</p>
<p>不输入密码直接登录</p>
<p>在论坛上也看见有人抱怨，家中的Ubuntu不能像Window$那样──不用输入密码就能 登录。其实同样能做到：</p>
<p>就在上一步的&#8220;安全&#8221;选项页中，勾选：</p>
<p>&#8220;启用自动登录&#8221;，&#8220;用户&#8221;选择（如：&#8220;me&#8221;）;</p>
<p>注意：公共用的计算机千万不能这么设置！</p>
<p><br>
SSH登录远程服务器</p>
<p>如果远程服务器只允许root用户SSH到服务器时，在Ubuntu下，必须&#8220;su
到root&#8221;用户才能登录成功(具体是看服务器端的配置)。</p>
<p><br>
首先，复制密钥到&#8220;/root/.ssh/&#8221;目录，</p>
<p><a  href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#109;&#101;&#64;&#116;&#105;&#112;&#102;&#111;&#111;&#58;&#37;&#55;&#69;&#36;">me@tipfoo:~$</a> su</p>
<p>Password:</p>
<p><a  href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#114;&#111;&#111;&#116;&#64;&#116;&#105;&#112;&#102;&#111;&#111;&#58;&#47;&#104;&#111;&#109;&#101;&#47;&#109;&#101;">root@tipfoo:/home/me</a>#
chmod 600 -R /root/.ssh/</p>
<p><a  href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#114;&#111;&#111;&#116;&#64;&#116;&#105;&#112;&#102;&#111;&#111;&#58;&#47;&#104;&#111;&#109;&#101;&#47;&#109;&#101;">root@tipfoo:/home/me</a>#
ssh -p 27482 11.22.33.44</p>
<p>Enter passphrase for key '/root/.ssh/id_rsa':</p>
<p>Last login: Thu Jun 21 14:29:00 2007 from 11.22.33.45</p>
修改开始菜单：直接在Ubuntu终端输入命令alacarte。可以任意增、改、隐藏、显示菜单，但无法删除菜单，即使拥有root权限<img src ="http://www.cppblog.com/guojingjia2006/aggbug/122944.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2010-08-10 16:26 <a href="http://www.cppblog.com/guojingjia2006/archive/2010/08/10/122944.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>win7 下恢复 ubuntu 10.04(转)</title><link>http://www.cppblog.com/guojingjia2006/archive/2010/08/10/122924.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Tue, 10 Aug 2010 05:29:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2010/08/10/122924.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/122924.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2010/08/10/122924.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/122924.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/122924.html</trackback:ping><description><![CDATA[<p><span style="color: #000000;">1. Win7与Ubuntu的安装顺序。如果你想装这两个系统，那么先装Win7，再装Ubuntu，就不会出现我上面的问题，可能是Grub比较亲和的缘故吧，呵呵...</span>
</p>
<p><span style="color: #000000;">2. 如果出现了我上面的那种情况，用Grub4Dos来解决你的问题。去<a href="http://download.csdn.net/source/2102326">我的资源</a>
里下载吧。注意，Grub4Dos文件夹下面有3个文件：g2ldr，g2ldr.mbr和隐藏的boot.ini。把这3个文件复制到Win7的主盘下面，然后重启进入Ubuntu之后，输入以下命令：</span>
</p>
<p><span style="color: #000000;">
<div class="dp-highlighter">
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="comment">/*</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">sudo&nbsp;grub-install&nbsp;/dev/sda</span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">sudo&nbsp;update-grub</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">*/</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<textarea style="display: none;" cols="50" rows="15" name="code" class="java">/*
sudo grub-install /dev/sda
sudo update-grub
*/</textarea>
</span>
</p>
<p><span style="color: #000000;">然后，再回到Win7中把Grub4Dos删除掉。这样重启就搞定了！<br>
</span>
</p>
<p><span style="color: #000000;">3. 如果你出现了上面的问题，用live CD安装了Grub，开机出现了Grub的命令提示符界面。输入以下命令，进入Win7：</span>
</p>
<p><span style="color: #000000;">
<div class="dp-highlighter">
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="comment">/*</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">root&nbsp;noverify&nbsp;(hd0,&nbsp;0)</span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">chainloader&nbsp;+1</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">boot</span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">*/</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<textarea style="display: none;" cols="50" rows="15" name="code" class="java">/*
root noverify (hd0, 0)
chainloader +1
boot
*/</textarea>
</span>
</p>
<p><span style="color: #000000;">然后下载mbrFix小工具修复mbr，然后把mbrFix放到C盘根目录下，然后打开cmd，切到C盘下面，运行这个命令：</span>
</p>
<p><span style="color: #000000;">
<div class="dp-highlighter">
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="comment">/*&nbsp;&nbsp;</span></span></li>
    <li class=""><span>mbrfix&nbsp;/drive&nbsp;0&nbsp;fixmbr&nbsp;&nbsp;</span></li>
    <li class="alt"><span>*/<span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<textarea style="display: none;" cols="50" rows="15" name="code" class="java">/*
mbrfix /drive 0 fixmbr
*/</textarea>
</span>
</p>
<p><span style="color: #000000;">这样那个讨厌的Grub命令提示界面就消失了。然后，按照第2步执行就好了。</span>
</p>
<p><span style="color: #000000;"><br>
</span>
</p>
<p><span style="color: #000000;">好了，这样Win7和Ubuntu就都顺利出现在开机之后的Grub列表
中了:)
最后，说下申请联想免费Win7升级盘的事情。前段时间，各个OEM厂商都给用户一个win7的免费升级计划，包括HP，Dell还有联想等厂家。于是，
大家都去申请了，搞笑的是，申请的时候，用户完全可以用虚假信息，以每张不到60元的价格&#8220;骗取&#8221;一张Win7旗舰版的安装光盘和厂家驱动盘。但是，后来
这个事儿让MS知道了，MS大怒。所以，后来用户如果要申请的话，需要提供购买笔记本或者台式机的证明，而且必须满足MS的升级规定。我就是在MS大怒之
后，不识相地去申请的，结果收到了联想否决的email，说我的小黑出厂是安装最低版的Vista，所以无法申请Win7光盘（因为当时在美国买的时候，
高版本的Vista要加不少钱，我没加:)。</span>
</p>
<p><span style="color: #000000;"><a href="http://www.cppblog.com/Files/guojingjia2006/Grub4Dos_mbrFix.rar">http://www.cppblog.com/Files/guojingjia2006/Grub4Dos_mbrFix.rar</a><br>
</span>
</p><img src ="http://www.cppblog.com/guojingjia2006/aggbug/122924.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2010-08-10 13:29 <a href="http://www.cppblog.com/guojingjia2006/archive/2010/08/10/122924.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于Uboot的NOR boot 或NAND boot问题---基于TQ2440（转载)</title><link>http://www.cppblog.com/guojingjia2006/archive/2010/08/09/122771.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Mon, 09 Aug 2010 06:04:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2010/08/09/122771.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/122771.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2010/08/09/122771.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/122771.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/122771.html</trackback:ping><description><![CDATA[好久没动开发板了，终于把研考完了，可以安心的做自己的实验了，但发现放下手头关于tq2440的实验两个多月，发现生疏了许多，许多问题都要想一下才能记起来是什么原理，真得抓紧时间好好弄了。
<p><wbr><wbr>又从uboot开始弄，以前移植了uboot1.3.1，由于太多匆忙，没有过多的注重细节，今天发现了一个以前忽略的问题，就是开发板自己判断是从何种flash介质启动的问题，首先说一下为什么要判断是哪种flash介质启动，因为这样就没有必要区分nor <wbr>boot还是nand <wbr>boot的bin文件了，bin文件烧到nor和nand都可以正常启动开发板。</p>
<p><wbr><wbr>在网上看了下别人关于nor boot或nand boot 的文章，发现Tekkaman <wbr>Ninja写的文章非常好，很值得推荐，附上地址，以便以后查找：<a  href="http://blog.chinaunix.net/u1/34474/showart.php?id=2085212"><font color="#6d5887">http://blog.chinaunix.net/u1/34474/showart.php?id=2085212</font></a></p>
<p><wbr><wbr>下面来分析下天嵌公司的uboot，据Tekkaman <wbr>Ninja说，天嵌的uboot是从openJTAG的uboot 借鉴过来的，这个我们姑且不管他。贴下天嵌TQ2440的uboot中关于启动判断的代码：</p>
<p>int bBootFrmNORFlash(void)<br>
{<br>
<wbr><wbr><wbr>volatile unsigned int *pdw = (volatile unsigned int *)0;<br>
<wbr><wbr><wbr>unsigned int dwVal;</p>
<p><wbr><wbr><wbr>dwVal = *pdw; <wbr><wbr><wbr><wbr><wbr><wbr><br>
<wbr><wbr><wbr>*pdw = 0x12345678;<br>
<wbr><wbr><wbr>if (*pdw != 0x12345678)<br>
<wbr><wbr><wbr>{<br>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr>return 1;<br>
<wbr><wbr><wbr>}<br>
<wbr><wbr><wbr>else<br>
<wbr><wbr><wbr>{<br>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr>*pdw = dwVal;<br>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr>return 0;<br>
<wbr><wbr><wbr>}<br>
}</p>
<p><wbr><wbr>这段代码的思想是这样的，无论是从NOR Flash还是从NAND Flash启动，地址0处为指令"b <wbr><wbr><wbr>Reset",
机器码为0xEA00000B，对于从NAND Flash启动的情况，其开始4KB的代码会复制到CPU内部4K内存中，对于从NOR
Flash启动的情况，NOR Flash的开始地址即为0。对于NOR
Flash，必须通过一定的命令序列才能写数据，所以可以根据这点差别来分辨是从NAND Flash还是NOR
Flash启动:向地址0写入一个数据，然后读出来，如果没有改变的话就是NOR Flash。</p>
<p><wbr><wbr><wbr>我们在深入的分析下，首先看下nand boot 和nor boot 时物理地址分配情况：</p>
<p><br></p>
<p><br></p>
<p><br></p>
<p>从NAND闪存启动U-BOOT的设计思路
</p>
<p><wbr><wbr><wbr>如果s3c2440被配置成从NAND闪存启动,上电后，s3c2440的NAND闪存控制器会自动把NAND闪存
中的前4K数据搬移到内部RAM中, 并把0x00000000设置为内部RAM的起始地址,
CPU从内部RAM的0x00000000位置开始启动。因此要把最核心的启动程序放在NAND闪存的前4K中。</p>
<p><wbr><wbr>当nor boot时，0x0000_0000是nor flash的起始地址，用语句*pdw = 0x12345678;
向0x0000_0000处写0x12345678，是没用的，因为对于NOR
Flash，必须通过一定的命令序列才能写数据，所以*pdw中存的数据仍然是"b <wbr><wbr><wbr>Reset",但当nand
flash启动时，cpu内部的4KBbootSRAM被映射到0x0000_0000开始的地址处，norflash这时无效了，这时用语句*pdw =
0x12345678;
向0x0000_0000处写0x12345678时，0x12345678会被写入，因为这是对内存的操作，不需要指令序列等，所以一旦发现写入和读出
的数据一致时，则可判断是nand boot，这时一定要把0x0000_0000处的数据还原，用*pdw = dwVal; 这句。</p>
<p><wbr><wbr>明天看看，得重新移植uboot了，好好研究研究，uboot很高深啊！！</p>
<p> </p>
<p><a  href="http://blog.sina.com.cn/s/blog_52009a100100hcv1.html">http://blog.sina.com.cn/s/blog_52009a100100hcv1.html</a></p><img src ="http://www.cppblog.com/guojingjia2006/aggbug/122771.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2010-08-09 14:04 <a href="http://www.cppblog.com/guojingjia2006/archive/2010/08/09/122771.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vim-系列-配置目录</title><link>http://www.cppblog.com/guojingjia2006/archive/2010/08/04/122231.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Wed, 04 Aug 2010 10:37:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2010/08/04/122231.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/122231.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2010/08/04/122231.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/122231.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/122231.html</trackback:ping><description><![CDATA[<p>一直对vim的配置目录很confused，我发现它的配置路径有好几个，除了home下面的.vim，还有/usr/share/vim/vim72和/usr/share/vim，三个目录到底哪个才是vim读取的路径呢？</p>
<p>经过我的几番尝试和小小Google了一下，终于得到了结果。原来vim的&#8220;runtimepath&#8221;共有三个，就是我上面所说的，但是vim读取这三个路径是有顺序的。</p>
<p>首先读取的目录就是$home/.vim,如果vim读取到了该目录下的syntax或者plugin，就不会再去读取usr目录了。</p>
<p>其次读取的目录是/usr/share/vim, 最后才读取/usr/share/vim/vim72。</p>
<p>我想vim的设计者这样设计是有原因的，当前登录用户的个性化设定肯定是优先考虑的，而/usr/share/vim是给所有用户使用的设置。所
以，对vim的设置和修改还是放在home目录比较好，一方面不会破坏系统原有设定，可以随时恢复，另一方面的好处我没有完全弄明白，具体请参见这位老兄
的文章<a  href="http://stackoverflow.com/questions/1384582/vim-linux-ubuntu-directory-location-vim-syntax" target="_blank">http://stackoverflow.com/questions/1384582/vim-linux-ubuntu-directory-location-vim-syntax</a></p>
<p>其实vim的documentation已经有很详细的描述了，在vim的command模式中输入:help &#8216;runtimepath&#8217; 可以看到详尽的解释。</p><img src ="http://www.cppblog.com/guojingjia2006/aggbug/122231.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2010-08-04 18:37 <a href="http://www.cppblog.com/guojingjia2006/archive/2010/08/04/122231.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>kubuntu 下ip地址和网关设置问题(转2)</title><link>http://www.cppblog.com/guojingjia2006/archive/2009/04/10/79453.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Fri, 10 Apr 2009 02:56:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2009/04/10/79453.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/79453.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2009/04/10/79453.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/79453.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/79453.html</trackback:ping><description><![CDATA[用wubi装了kubuntu 8.10正式版，然后设置右下角的网络连接，设置好了IP,子网掩码，默认网关，和DNS后还是无法连接网络，但是这在ubuntu和xubuntu上一点问题都没有。
kubuntu界面非常漂亮，可就是无法设置IP上网，这样就没办法更新，没办法安装软件了啦。
难道是要开启root用户？ubuntu下我会操作可是kubuntu就不怎么会了。另外或许用终端执行IP配置，怎么执行操作呢？

我已经获得root权限，但是不知道怎么设置允许root登陆，在默认帐户登陆后打开终端，输入su 输入密码进入root权限#执行 sudo vi /etc/network/interfaces，弹出几段英文，然后按Enter之后却不能编辑啊。如果用kate命令也不行。
晕死了！对kubuntu非常气愤！

会的话加我的QQ聊，这样更快点578445003，我隐身

另外说明一下，我用过ubuntu和xubunu，我是按照在Windows上的IP参数设置的，可以连接上网，可是到了kubuntu就不行了。

经过参阅各种资料加上自己的创新，已经成功解决，方法如下：
1.通过wubi安装好kubuntu后，打开终端，获取root权限，执行sudo passwd
然后输入密码两次，在输入新密码，成功。
2.允许root登录，因为在标准帐户下，在终端执行sudo kate /etc/network/interfaces无法弹出文本编辑，反正执行kate命令总是提示无法连接到 x server：0.0。于是打算修改/etc/kde4/kdm/kdmrc文件来获得root用户登录。但是我刚刚说过无法在终端执行kate命令，于是直接进入文件管理器窗口，进入到/etc/kde4/kdm,找到kdmrc，单击它，发现一篇灿烂的曙光，可以打开，找到AllowRootLogin=false这一行，把fasle改为true，当然因为不是用root权限打开的所以无法直接保存（save），那么就改变思路另存为（save as）另存到标准帐户的home文件夹内，关闭kate。然后打开终端，执行su，输入密码获得root权限，执行删除刚才的/etc/kde4/kdm/kdmrc文件，命令为 rm /etc/kde4/kdm/kdmrc，然后复制刚刚另存为的文件到/etc/kde4/kdm/目录下，执行命令 cp kdmrc /etc/kde4/kdm。
3.重启kubuntu，使用root登录，这样就不会出现root不允许登录的问题。接下来就是修改 /etc/network/interfaces文件了，可以在文件管理器中直接打开 /etc/network/interfaces文件，然后删除里面的内容，并输入新的内容
auto eth0 #
iface eth0 inet static
address 192.168.1.27 #
netmask 255.255.255.0 #
gateway 192.168.1.1 #
保存，
修改DNS，修改/etc/resolv.conf文件，因为在文件管理器中找不到/etc/resolv.conf文件所以应该是隐藏了，那么就用终端执行修改
打开终端，执行sudo kate /etc/resolv.conf，这下kate可以正常打开了，然后在里面输入
nameserver 202.103.224.68 ＃
nameserver 202.103.225.68 ＃
保存关闭，
4.在终端中执行sudo service networking restart
好了终端里面显示［OK］之后就可以正常上网了。
<img src ="http://www.cppblog.com/guojingjia2006/aggbug/79453.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2009-04-10 10:56 <a href="http://www.cppblog.com/guojingjia2006/archive/2009/04/10/79453.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux下Netbeans字体解决(转)</title><link>http://www.cppblog.com/guojingjia2006/archive/2009/04/08/79283.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Wed, 08 Apr 2009 09:17:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2009/04/08/79283.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/79283.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2009/04/08/79283.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/79283.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/79283.html</trackback:ping><description><![CDATA[ 今天装了netbeans6.0.1，不过那字体让人难以忍受，找了半天，终于找到一个解决的了，感谢作者...供自己以后学习(我用的是kubuntu)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2009-03-09 09:12
Linux版本：Ubuntu 8.10 
 Netbeans: Netbeans6.5
 参考链接：http://blog.csdn.net/mosesgi/archive/2007/08/26/1759272.aspx
 1.修改JRE字体配置文件：
              进入JRE字体配置文件目录
                  cd $JAVA_HOME/jre/lib
             备份要修改的配置文件 
                 sudo cp fontconfig.properties fontconfig.properties.backup 
             将fontconfig.properties 的内容替换为以下内容 （复制自Jimuchen）
 # @(#)fontconfig.properties    1.5 04/01/28
 #
 # Copyright 2003 Sun Microsystems, Inc. All rights reserved.
 #
 
 # Version
 
 version=1
 
 # Component Font Mappings
 
 allfonts.chinese-ms936=SimSun
 allfonts.chinese-gb18030=SimSun-18030
 allfonts.chinese-hkscs=MingLiU_HKSCS
 allfonts.devanagari=Mangal
 allfonts.dingbats=Wingdings
 allfonts.lucida=Lucida Sans Regular
 allfonts.symbol=Symbol
 allfonts.thai=Lucida Sans Regular
 
 serif.plain.alphabetic=Times New Roman
 serif.plain.chinese-ms950=MingLiU
 serif.plain.hebrew=David
 serif.plain.japanese=MS Mincho
 serif.plain.korean=Batang
 
 serif.bold.alphabetic=Times New Roman Bold
 serif.bold.chinese-ms950=PMingLiU
 serif.bold.hebrew=David Bold
 serif.bold.japanese=MS Mincho
 serif.bold.korean=Batang
 
 serif.italic.alphabetic=Times New Roman Italic
 serif.italic.chinese-ms950=PMingLiU
 serif.italic.hebrew=David
 serif.italic.japanese=MS Mincho
 serif.italic.korean=Batang
 
 serif.bolditalic.alphabetic=Times New Roman Bold Italic
 serif.bolditalic.chinese-ms950=PMingLiU
 serif.bolditalic.hebrew=David Bold
 serif.bolditalic.japanese=MS Mincho
 serif.bolditalic.korean=Batang
 
 sansserif.plain.alphabetic=Arial
 sansserif.plain.chinese-ms950=MingLiU
 sansserif.plain.hebrew=David
 sansserif.plain.japanese=MS Gothic
 sansserif.plain.korean=Gulim
 
 sansserif.bold.alphabetic=Arial Bold
 sansserif.bold.chinese-ms950=PMingLiU
 sansserif.bold.hebrew=David Bold
 sansserif.bold.japanese=MS Gothic
 sansserif.bold.korean=Gulim
 
 sansserif.italic.alphabetic=Arial Italic
 sansserif.italic.chinese-ms950=PMingLiU
 sansserif.italic.hebrew=David
 sansserif.italic.japanese=MS Gothic
 sansserif.italic.korean=Gulim
 
 sansserif.bolditalic.alphabetic=Arial Bold Italic
 sansserif.bolditalic.chinese-ms950=PMingLiU
 sansserif.bolditalic.hebrew=David Bold
 sansserif.bolditalic.japanese=MS Gothic
 sansserif.bolditalic.korean=Gulim
 
 monospaced.plain.alphabetic=Courier New
 monospaced.plain.chinese-ms950=MingLiU
 monospaced.plain.hebrew=David
 monospaced.plain.japanese=MS Gothic
 monospaced.plain.korean=GulimChe
 
 monospaced.bold.alphabetic=Courier New Bold
 monospaced.bold.chinese-ms950=PMingLiU
 monospaced.bold.hebrew=David Bold
 monospaced.bold.japanese=MS Gothic
 monospaced.bold.korean=GulimChe
 
 monospaced.italic.alphabetic=Courier New Italic
 monospaced.italic.chinese-ms950=PMingLiU
 monospaced.italic.hebrew=David
 monospaced.italic.japanese=MS Gothic
 monospaced.italic.korean=GulimChe
 
 monospaced.bolditalic.alphabetic=Courier New Bold Italic
 monospaced.bolditalic.chinese-ms950=PMingLiU
 monospaced.bolditalic.hebrew=David Bold
 monospaced.bolditalic.japanese=MS Gothic
 monospaced.bolditalic.korean=GulimChe
 
 dialog.plain.alphabetic=Arial
 dialog.plain.chinese-ms950=MingLiU
 dialog.plain.hebrew=David
 dialog.plain.japanese=MS Gothic
 dialog.plain.korean=Gulim
 
 dialog.bold.alphabetic=Arial Bold
 dialog.bold.chinese-ms950=PMingLiU
 dialog.bold.hebrew=David Bold
 dialog.bold.japanese=MS Gothic
 dialog.bold.korean=Gulim
 
 dialog.italic.alphabetic=Arial Italic
 dialog.italic.chinese-ms950=PMingLiU
 dialog.italic.hebrew=David
 dialog.italic.japanese=MS Gothic
 dialog.italic.korean=Gulim
 
 dialog.bolditalic.alphabetic=Arial Bold Italic
 dialog.bolditalic.chinese-ms950=PMingLiU
 dialog.bolditalic.hebrew=David Bold
 dialog.bolditalic.japanese=MS Gothic
 dialog.bolditalic.korean=Gulim
 
 dialoginput.plain.alphabetic=Verdana
 dialoginput.plain.chinese-ms950=STXIHEI
 dialoginput.plain.hebrew=David
 dialoginput.plain.japanese=MS Gothic
 dialoginput.plain.korean=Gulim
 
 dialoginput.bold.alphabetic=Verdana Bold
 dialoginput.bold.chinese-ms950=STXIHEI
 dialoginput.bold.hebrew=David Bold
 dialoginput.bold.japanese=MS Gothic
 dialoginput.bold.korean=Gulim
 
 dialoginput.italic.alphabetic=Verdana Italic
 dialoginput.italic.chinese-ms950=STXIHEI
 dialoginput.italic.hebrew=David
 dialoginput.italic.japanese=MS Gothic
 dialoginput.italic.korean=Gulim
 
 dialoginput.bolditalic.alphabetic=Verdana Bold Italic
 dialoginput.bolditalic.chinese-ms950=STXIHEI
 dialoginput.bolditalic.hebrew=David Bold
 dialoginput.bolditalic.japanese=MS Gothic
 dialoginput.bolditalic.korean=Gulim
 
 
 
 # Search Sequences
 
 sequence.allfonts=alphabetic/default,dingbats,symbol
 
 sequence.serif.GBK=alphabetic,chinese-ms936,dingbats,symbol
 sequence.sansserif.GBK=alphabetic,chinese-ms936,dingbats,symbol
 sequence.monospaced.GBK=chinese-ms936,alphabetic,dingbats,symbol
 sequence.dialog.GBK=alphabetic,chinese-ms936,dingbats,symbol
 sequence.dialoginput.GBK=alphabetic,chinese-ms936,dingbats,symbol
 
 sequence.serif.GB18030=alphabetic,chinese-gb18030,dingbats,symbol
 sequence.sansserif.GB18030=alphabetic,chinese-gb18030,dingbats,symbol
 sequence.monospaced.GB18030=chinese-gb18030,alphabetic,dingbats,symbol
 sequence.dialog.GB18030=alphabetic,chinese-gb18030,dingbats,symbol
 sequence.dialoginput.GB18030=alphabetic,chinese-gb18030,dingbats,symbol
 
 sequence.serif.x-windows-950=alphabetic,chinese-ms950,dingbats,symbol
 sequence.sansserif.x-windows-950=alphabetic,chinese-ms950,dingbats,symbol
 sequence.monospaced.x-windows-950=chinese-ms950,alphabetic,dingbats,symbol
 sequence.dialog.x-windows-950=alphabetic,chinese-ms950,dingbats,symbol
 sequence.dialoginput.x-windows-950=alphabetic,chinese-ms950,dingbats,symbol
 
 sequence.serif.x-MS950-HKSCS=alphabetic,chinese-ms950,chinese-hkscs,dingbats,symbol
 sequence.sansserif.x-MS950-HKSCS=alphabetic,chinese-ms950,chinese-hkscs,dingbats,symbol
 sequence.monospaced.x-MS950-HKSCS=chinese-ms950,alphabetic,chinese-hkscs,dingbats,symbol
 sequence.dialog.x-MS950-HKSCS=alphabetic,chinese-ms950,chinese-hkscs,dingbats,symbol
 sequence.dialoginput.x-MS950-HKSCS=alphabetic,chinese-ms950,chinese-hkscs,dingbats,symbol
 
 sequence.allfonts.UTF-8.hi=alphabetic/1252,devanagari,dingbats,symbol
 
 sequence.allfonts.windows-1255=hebrew,alphabetic/1252,dingbats,symbol
 
 sequence.serif.windows-31j=alphabetic,japanese,dingbats,symbol
 sequence.sansserif.windows-31j=alphabetic,japanese,dingbats,symbol
 sequence.monospaced.windows-31j=japanese,alphabetic,dingbats,symbol
 sequence.dialog.windows-31j=alphabetic,japanese,dingbats,symbol
 sequence.dialoginput.windows-31j=alphabetic,japanese,dingbats,symbol
 
 sequence.serif.x-windows-949=alphabetic,korean,dingbats,symbol
 sequence.sansserif.x-windows-949=alphabetic,korean,dingbats,symbol
 sequence.monospaced.x-windows-949=korean,alphabetic,dingbats,symbol
 sequence.dialog.x-windows-949=alphabetic,korean,dingbats,symbol
 sequence.dialoginput.x-windows-949=alphabetic,korean,dingbats,symbol
 
 sequence.allfonts.x-windows-874=alphabetic,thai,dingbats,symbol
 
 sequence.fallback=lucida,
                   chinese-ms950,chinese-hkscs,chinese-ms936,chinese-gb18030,
                   japanese,korean
 
 # Exclusion Ranges
 
 exclusion.alphabetic=0700-1e9f,1f00-20ab,20ad-f8ff
 exclusion.chinese-gb18030=0390-03d6,2200-22ef,2701-27be
 exclusion.hebrew=0041-005a,0060-007a,007f-00ff,20ac-20ac
 
 # Monospaced to Proportional width variant mapping
 # (Experimental private syntax)
 proportional.MS_Gothic=MS PGothic
 proportional.MS_Mincho=MS PMincho
 proportional.MingLiU=PMingLiU
 
 # Font File Names
 
 filename.Arial=ARIAL.TTF
 filename.Arial_Bold=ARIALBD.TTF
 filename.Arial_Italic=ARIALI.TTF
 filename.Arial_Bold_Italic=ARIALBI.TTF
 
 filename.Courier_New=COUR.TTF
 filename.Courier_New_Bold=COURBD.TTF
 filename.Courier_New_Italic=COURI.TTF
 filename.Courier_New_Bold_Italic=COURBI.TTF
 
 filename.Times_New_Roman=TIMES.TTF
 filename.Times_New_Roman_Bold=TIMESBD.TTF
 filename.Times_New_Roman_Italic=TIMESI.TTF
 filename.Times_New_Roman_Bold_Italic=TIMESBI.TTF
 
 
 filename.Verdana=verdana.TTF
 filename.Verdana_Bold=verdanab.TTF
 filename.Verdana_Italic=verdanai.TTF
 filename.Verdana_Bold_Italic=verdanaz.TTF
 
 filename.SimSun=SIMSUN.TTC
 filename.SimSun-18030=SIMSUN18030.TTC
 
 filename.MingLiU=MINGLIU.TTC
 filename.PMingLiU=MINGLIU.TTC
 filename.MingLiU_HKSCS=hkscsm3u.ttf
 filename.STXIHEI=STXIHEI.TTF
 
 filename.David=DAVID.TTF
 filename.David_Bold=DAVIDBD.TTF
 
 filename.MS_Mincho=MSMINCHO.TTC
 filename.MS_PMincho=MSMINCHO.TTC
 filename.MS_Gothic=MSGOTHIC.TTC
 filename.MS_PGothic=MSGOTHIC.TTC
 
 filename.Gulim=gulim.TTC
 filename.Batang=batang.TTC
 filename.GulimChe=gulim.TTC
 
 filename.Lucida_Sans_Regular=LucidaSansRegular.ttf
 filename.Mangal=MANGAL.TTF
 filename.Symbol=SYMBOL.TTF
 filename.Wingdings=WINGDING.TTF
 
 2.修改 ＄NETBEANS＿HOME/etc/netbeans.conf
 将其中的
 netbeans_default_options="-J-client -J-Xverify:none -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-XX:MaxPermSize=200m -J-Dapple.laf.useScreenMenuBar=true -J-Dsun.java2d.noddraw=truei "
 改为
 netbeans_default_options="-J-client -J-Xverify:none -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-XX:MaxPermSize=200m -J-Dapple.laf.useScreenMenuBar=true -J-Dsun.java2d.noddraw=truei -J-Dawt.useSystemAAFontSettings=on"
 即可。<img src ="http://www.cppblog.com/guojingjia2006/aggbug/79283.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2009-04-08 17:17 <a href="http://www.cppblog.com/guojingjia2006/archive/2009/04/08/79283.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>amarok音乐标题乱码解决</title><link>http://www.cppblog.com/guojingjia2006/archive/2009/04/08/79241.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Wed, 08 Apr 2009 03:10:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2009/04/08/79241.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/79241.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2009/04/08/79241.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/79241.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/79241.html</trackback:ping><description><![CDATA[ 下载软件mutagen，安装成功，使用命令
 
 mid3iconv *mp3 --encoding=GBK
 
 可以将当前目录下的mp3文件的id3 tag信息转换成utf8编码。
 <img src ="http://www.cppblog.com/guojingjia2006/aggbug/79241.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2009-04-08 11:10 <a href="http://www.cppblog.com/guojingjia2006/archive/2009/04/08/79241.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>