<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title><![CDATA[小峰网络遨游记]]></title>
  <subtitle><![CDATA[记录80后的网络生活]]></subtitle>
  <link href="/atom.xml" rel="self"/>
  <link href="http://xfeng.me/"/>
  <updated>2015-12-25T04:05:44.000Z</updated>
  <id>http://xfeng.me/</id>
  
  <author>
    <name><![CDATA[Marvin]]></name>
    <email><![CDATA[me@joysboy.net]]></email>
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title><![CDATA[升级Hexo3记录]]></title>
    <link href="http://xfeng.me/upgrade-hexo3/"/>
    <id>http://xfeng.me/upgrade-hexo3/</id>
    <published>2015-05-24T02:51:43.000Z</published>
    <updated>2015-12-25T04:05:44.000Z</updated>
    <content type="html"><![CDATA[<p>Hexo3发布已经很久了，一直没时间折腾升级</p>
<p>其实刚发布时尝试升级过，但是generate文章经常报错，文章分类生成后不合并，问题非常多，然后就等稳定点再升级了，一拖就拖到了现在</p>
<p>其实感觉Hexo3新版的特性对我没啥用，只是手贱喜欢新版</p>
<p>官方新版的特性说明如下：
  <br>
  <blockquote>
    <ul>
      <li>New CLI: Command line interface is separated into a stand-alone module: hexo-cli</li>
      <li>Slimmer Core Module: Generators, deployers and server are also separated from the main module.</li>
      <li>New Generator API: Generator API changed a lot in Hexo 3.</li>
      <li>Include Assets in a Post: Serveral useful tag plugins are added in Hexo 3: post_path, post_link, asset_path, asset_link, asset_img.</li>
      <li>Async Tag Plugins: Tag plugins can do async jobs now!</li>
      <li>Timezone Support: You can define the timezone of your site now.</li>
    </ul>
    <footer><strong>Hexo</strong><cite><a href="http://hexo.io/news/2015/03/05/hexo-3-0-released/" target="_blank" rel="external">Hexo 3.0 Released</a></cite></footer>
  </blockquote>
</p>
<p>新版虽然没提供啥对我有用的功能，但是升级的兼容性让我折腾了一番</p>
<p>因为我的所有文章md文件是放git保存的，最后干脆重新init一个Hexo 3的目录，重新配置，然后将文章源码拷贝过来，这样感觉效率更好，也避免2到3中间残留的某些代码导致各种诡异问题
  <br>
  <a id="more"></a>
</p>
<h3 id="Plugins"><a href="#Plugins" class="headerlink" title="Plugins"></a>Plugins</h3>
<p>首先是插件，Hexo 3将很多功能从核心代码中拆出来作为插件了，下面是我安装的插件</p>
<h4 id="Generator_Plugins"><a href="#Generator_Plugins" class="headerlink" title="Generator Plugins"></a>Generator Plugins</h4>
<p>负责生成对应内容的插件，Hexo init的时候应该已经自动安装前三个了，feed和sitemap需要手工安装
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td>
        <td class="code"><pre><span class="line">npm install hexo-generator-archive --save</span><br><span class="line">npm install hexo-generator-category --save</span><br><span class="line">npm install hexo-generator-tag --save</span><br><span class="line">npm install hexo-generator-feed --save</span><br><span class="line">npm install hexo-generator-sitemap --save</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>原来在sitemap中自己修改了代码，让生成的XML中包含category和tag，并且和post不同的权重，重装之后也懒得改了</p>
<h4 id="Optimize_Plugins"><a href="#Optimize_Plugins" class="headerlink" title="Optimize Plugins"></a>Optimize Plugins</h4>
<p>用户压缩代码用的插件，似乎css不用插件也会自己压缩，不过我还是安装了clean-css，另外还有一个html-minifly，但是一直不生效，懒得折腾删除了
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td>
        <td class="code"><pre><span class="line">npm install hexo-clean-css --save</span><br><span class="line">npm install hexo-uglify --save</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<h4 id="Deploy_Plugins"><a href="#Deploy_Plugins" class="headerlink" title="Deploy Plugins"></a>Deploy Plugins</h4>
<p>Hexo 3的时候官方提供了ftp部署插件，原来的jsftp插件貌似不兼容了，不过官方的ftpsync在万网的主机上不好使，我使用客户端上传时也是没传几个文件就会超时，然后重连，但是这个插件没有那么强的容错处理，所以每次传几个文件就报错了。。。无奈
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td>
        <td class="code"><pre><span class="line">npm install hexo-deployer-rsync --save</span><br><span class="line">npm install hexo-deployer-ftpsync --save</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<h3 id="Theme"><a href="#Theme" class="headerlink" title="Theme"></a>Theme</h3>
<p>主题依然是用官方的Landscape修改出来的，和原来Hexo2的基本不变，因为是官方提供的，没有什么不兼容的部分</p>
<p>自己增加的模块主要有百度分享、百度推荐、Adsense、多说评论、文章声明，还有TOC</p>
<p>没有使用官方函数的的地方就一个，文章分类，为了让Google解析的时候能获取到更多信息，分类上增加Breadcrumb属性，因为官方的list_categories没法支持，Hexo2的时候我直接改源码了，但是后面升级冲突很恶心，所以这次自己在模板里写js好了</p>
<p>大概代码如下
  <br>
  <figure class="highlight javascript">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td>
        <td class="code"><pre><span class="line">&lt;% <span class="keyword">if</span> (post.categories &amp;&amp; post.categories.length)&#123; %&gt;</span><br><span class="line">  <span class="xml"><span class="tag">&lt;<span class="title">div</span> <span class="attribute">class</span>=<span class="value">"article-category"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="title">%</span> <span class="attribute">if</span> (<span class="attribute">index</span>)&#123; %&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="title">%-</span> <span class="attribute">list_categories</span>(<span class="attribute">post.categories</span>, &#123;</span><br><span class="line">      <span class="attribute">show_count:</span> <span class="attribute">false</span>,</span><br><span class="line">      <span class="attribute">class:</span> '<span class="attribute">article-category</span>',</span><br><span class="line">      <span class="attribute">style:</span> '<span class="attribute">none</span>',</span><br><span class="line">      <span class="attribute">separator:</span> '►'</span><br><span class="line">    &#125;) %&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="title">%</span> &#125; <span class="attribute">else</span> &#123; %&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="title">%</span></span><br><span class="line">      <span class="attribute">var</span> <span class="attribute">cats</span> = [];</span><br><span class="line">      <span class="attribute">post.categories.forEach</span>(<span class="attribute">function</span>(<span class="attribute">cat</span>)&#123;</span><br><span class="line">        <span class="attribute">cats.push</span>('&lt;<span class="attribute">span</span> <span class="attribute">itemscope</span> <span class="attribute">itemtype</span>=<span class="value">"http://data-vocabulary.org/Breadcrumb"</span>&gt;</span><span class="tag">&lt;<span class="title">a</span> <span class="attribute">class</span>=<span class="value">"article-category-link"</span> <span class="attribute">href</span>=<span class="value">"' + url_for(cat.path) + '"</span> <span class="attribute">itemprop</span>=<span class="value">"url"</span>&gt;</span><span class="tag">&lt;<span class="title">span</span> <span class="attribute">itemprop</span>=<span class="value">"title"</span>&gt;</span>' + trim(cat.name) + '<span class="tag">&lt;/<span class="title">span</span>&gt;</span><span class="tag">&lt;/<span class="title">a</span>&gt;</span><span class="tag">&lt;/<span class="title">span</span>&gt;</span>')</span><br><span class="line">      &#125;);</span><br><span class="line">    %&gt;</span><br><span class="line">    <span class="tag">&lt;<span class="title">%-</span> <span class="attribute">cats.join</span>('►') %&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="title">%</span> &#125; %&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="title">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="title">%</span> &#125; %&gt;</span></span></span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<h3 id="u90E8_u7F72"><a href="#u90E8_u7F72" class="headerlink" title="部署"></a>部署</h3>
<p>全部修改完，Generate成功后就是部署到主机了，因为搞到了万网的免费主机，所以放弃我的破VPS了，但是只能使用ftp，并且ftp插件还不能正常运行，蛋疼的只能generate完成后找客户端上传,如果可以使用rsync就好了</p>
<p>废话那么多，主要是觉得自己半年多都没一篇文章了，除草。。。</p>]]></content>
    <summary type="html">
    <![CDATA[<p>Hexo3发布已经很久了，一直没时间折腾升级</p>
<p>其实刚发布时尝试升级过，但是generate文章经常报错，文章分类生成后不合并，问题非常多，然后就等稳定点再升级了，一拖就拖到了现在</p>
<p>其实感觉Hexo3新版的特性对我没啥用，只是手贱喜欢新版</p>
<p>官方新版的特性说明如下：
  <br>
  <blockquote>
    <ul>
      <li>New CLI: Command line interface is separated into a stand-alone module: hexo-cli</li>
      <li>Slimmer Core Module: Generators, deployers and server are also separated from the main module.</li>
      <li>New Generator API: Generator API changed a lot in Hexo 3.</li>
      <li>Include Assets in a Post: Serveral useful tag plugins are added in Hexo 3: post_path, post_link, asset_path, asset_link, asset_img.</li>
      <li>Async Tag Plugins: Tag plugins can do async jobs now!</li>
      <li>Timezone Support: You can define the timezone of your site now.</li>
    </ul>
    <footer><strong>Hexo</strong><cite><a href="http://hexo.io/news/2015/03/05/hexo-3-0-released/">Hexo 3.0 Released</a></cite></footer>
  </blockquote>
</p>
<p>新版虽然没提供啥对我有用的功能，但是升级的兼容性让我折腾了一番</p>
<p>因为我的所有文章md文件是放git保存的，最后干脆重新init一个Hexo 3的目录，重新配置，然后将文章源码拷贝过来，这样感觉效率更好，也避免2到3中间残留的某些代码导致各种诡异问题
  <br>]]>
    
    </summary>
    
      <category term="hexo" scheme="http://xfeng.me/tags/hexo/"/>
    
      <category term="plugin" scheme="http://xfeng.me/tags/plugin/"/>
    
      <category term="theme" scheme="http://xfeng.me/tags/theme/"/>
    
      <category term="Jottings" scheme="http://xfeng.me/category/jottings/"/>
    
      <category term="Web" scheme="http://xfeng.me/category/jottings/web/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[XFeng.Me备案成功]]></title>
    <link href="http://xfeng.me/domain-beian-success/"/>
    <id>http://xfeng.me/domain-beian-success/</id>
    <published>2015-02-10T05:29:49.000Z</published>
    <updated>2015-12-25T04:05:44.000Z</updated>
    <content type="html"><![CDATA[<p>阿里云万网提供免费主机，为支持我厂产品，立马去抢了一个，阿里云还提供免费备案，正好有机会可以给xfeng.me备案了</p>
<p>网上总是看到有人说上海备案非常快，3天左右就全部搞定，这次备案来看，杭州速度马马虎虎，第一次新增域名，和第二次修改主体信息，都是刚好8天时间审批通过</p>
<p>这次备案还是用了08年备案joysboy.net的备案号，不用注销重新备案真好，不过现在备案麻烦多了，还需要半身照，折腾半天也不错，很多限制备案才能使用的服务都能使用了，upyun可以使用xfeng.me的二级域名了</p>
<p>废话不多说了，万网免费主机可以使用两年，需要的赶紧去抢一个吧，每天限量，凌晨12点一过，必定能抢到</p>]]></content>
    <summary type="html">
    <![CDATA[<p>阿里云万网提供免费主机，为支持我厂产品，立马去抢了一个，阿里云还提供免费备案，正好有机会可以给xfeng.me备案了</p>
<p>网上总是看到有人说上海备案非常快，3天左右就全部搞定，这次备案来看，杭州速度马马虎虎，第一次新增域名，和第二次修改主体信息，都是刚好8天时间审]]>
    </summary>
    
      <category term="beian" scheme="http://xfeng.me/tags/beian/"/>
    
      <category term="Jottings" scheme="http://xfeng.me/category/jottings/"/>
    
      <category term="Web" scheme="http://xfeng.me/category/jottings/web/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[让Nginx支持CGI执行Bash,Python等脚本]]></title>
    <link href="http://xfeng.me/nginx-support-fcgi/"/>
    <id>http://xfeng.me/nginx-support-fcgi/</id>
    <published>2015-01-29T05:29:49.000Z</published>
    <updated>2015-12-25T04:05:44.000Z</updated>
    <content type="html"><![CDATA[<p>由于想通过页面查看VPS使用的流量，以前用的是vnstat，非常不错的一个工具，但是几个前端插件都是需要PHP环境，但是现在将博客改用Hexo后，完全静态化，只启动了一个Nginx，不想启动php-fpm，最后找到了vnstatsvg这个项目，使用CGI的方式来获取数据，最后生成svg图片来展示，满足我的需求。</p>
<p>那问题就来了，我后端使用的是Nginx，并非Httpd，Nginx原生不支持CGI执行，之前工作上写的很多CGI都是通过Apache Httpd来执行，以前虽然看过Nginx使用fcgi执行CGI脚本的文章，但从没实践过，这次实战一次。</p>
<h2 id="spawn-fcgi"><a href="#spawn-fcgi" class="headerlink" title="spawn-fcgi"></a><strong>spawn-fcgi</strong></h2>
<p>spawn-fcgi原来是Lighttpd中的模块，现在已经独立出来，由于Nginx不能直接执行外部CGI程序，因此需要依赖spawn-fcgi来执行</p>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td>
      <td class="code"><pre><span class="line">git <span class="built_in">clone</span> git@github.com:lighttpd/spawn-fcgi.git</span><br><span class="line"><span class="built_in">cd</span> spawn-fcgi</span><br><span class="line">./autogen.sh</span><br><span class="line">./configure</span><br><span class="line">make &amp;&amp; make install</span><br></pre></td>
    </tr>
  </table>
</figure>
<p>从github获取spawn-fcgi最新代码，然后编译安装
  <br>
  <a id="more"></a>
</p>
<h2 id="fcgi"><a href="#fcgi" class="headerlink" title="fcgi"></a><strong>fcgi</strong></h2>
<p>安装完spawn-fcgi，还需要安装fcgi的库，我使用的系统是CentOS 6，所以直接去找了fcgi的rpm包安装，当然你也可以下载源码编译安装</p>
<p>如果通过rpm包安装，因为还有fcgiwrap需要依赖fcgi的库编译，因此还需要将fcgi-devel也安装</p>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td>
      <td class="code"><pre><span class="line">wget http://www.rpmseek.com/download/http://download.opensuse.org/repositories/home:/csbuild:/centosextra/CentOS_CentOS-<span class="number">6</span>/i686/fcgi-<span class="number">2.4</span>.<span class="number">1</span>-<span class="number">2.3</span>.i686.rpm</span><br><span class="line">wget ftp://ftp.pbone.net/mirror/ftp5.gwdg.de/pub/opensuse/repositories/home:/csbuild:/centosextra/CentOS_CentOS-<span class="number">6</span>/i686/fcgi-devel-<span class="number">2.4</span>.<span class="number">1</span>-<span class="number">2.3</span>.i686.rpm</span><br><span class="line">rpm -ivh fcgi-<span class="number">2.4</span>.<span class="number">1</span>-<span class="number">2.3</span>.i686.rpm</span><br><span class="line">rpm -ivh fcgi-devel-<span class="number">2.4</span>.<span class="number">1</span>-<span class="number">2.3</span>.i686.rpm</span><br></pre></td>
    </tr>
  </table>
</figure>
<h2 id="fcgiwrap"><a href="#fcgiwrap" class="headerlink" title="fcgiwrap"></a><strong>fcgiwrap</strong></h2>
<p>最后就是安装fcgiwrap，这是一个非常轻量让Nginx执行CGI程序的wrapper</p>
<p>从github获取最新版编译安装</p>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td>
      <td class="code"><pre><span class="line">git <span class="built_in">clone</span> git@github.com:gnosek/fcgiwrap.git</span><br><span class="line"><span class="built_in">cd</span> fcgiwrap</span><br><span class="line">autoreconf -i</span><br><span class="line">./configure</span><br><span class="line">make &amp;&amp; make install</span><br></pre></td>
    </tr>
  </table>
</figure>
<h2 id="fcgiwrap__u542F_u52A8_u811A_u672C"><a href="#fcgiwrap__u542F_u52A8_u811A_u672C" class="headerlink" title="fcgiwrap 启动脚本"></a><strong>fcgiwrap 启动脚本</strong></h2>
<p>为了可以方便的启动或停止fcgiwrap，使用RH或者CentOS的用户都可以使用这个方法，编写一个名为fcgiwarp的shell脚本放入/etc/init.d</p>
<p>脚本内容如下，需要注意你的spawn-fcgi和fcgiwrap的安装目录是否和我一致，不一致请修改，还有Nginx的执行用户是否也为www，如果不是请改为你使用的用户</p>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br></pre></td>
      <td class="code"><pre><span class="line"><span class="shebang">#! /bin/bash</span></span><br><span class="line"><span class="comment">### BEGIN INIT INFO</span></span><br><span class="line"><span class="comment"># Provides:          fcgiwrap</span></span><br><span class="line"><span class="comment"># Required-Start:    $remote_fs</span></span><br><span class="line"><span class="comment"># Required-Stop:     $remote_fs</span></span><br><span class="line"><span class="comment"># Should-Start:</span></span><br><span class="line"><span class="comment"># Should-Stop:</span></span><br><span class="line"><span class="comment"># Default-Start:     2 3 4 5</span></span><br><span class="line"><span class="comment"># Default-Stop:      0 1 6</span></span><br><span class="line"><span class="comment"># Short-Description: FastCGI wrapper</span></span><br><span class="line"><span class="comment"># Description:       Simple server for running CGI applications over FastCGI</span></span><br><span class="line"><span class="comment">### END INIT INFO</span></span><br><span class="line"></span><br><span class="line">PATH=/usr/<span class="built_in">local</span>/sbin:/usr/<span class="built_in">local</span>/bin:/sbin:/bin:/usr/sbin:/usr/bin</span><br><span class="line">SPAWN_FCGI=<span class="string">"/usr/local/bin/spawn-fcgi"</span></span><br><span class="line">DAEMON=<span class="string">"/usr/local/sbin/fcgiwrap"</span></span><br><span class="line">NAME=<span class="string">"fcgiwrap"</span></span><br><span class="line"></span><br><span class="line">PIDFILE=<span class="string">"/var/run/<span class="variable">$NAME</span>.pid"</span></span><br><span class="line"></span><br><span class="line">FCGI_SOCKET=<span class="string">"/tmp/<span class="variable">$NAME</span>.socket"</span></span><br><span class="line">FCGI_USER=<span class="string">"www"</span></span><br><span class="line">FCGI_GROUP=<span class="string">"www"</span></span><br><span class="line">FORK_NUM=<span class="number">5</span></span><br><span class="line">SCRIPTNAME=/etc/init.d/<span class="variable">$NAME</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">case</span> <span class="string">"<span class="variable">$1</span>"</span> <span class="keyword">in</span></span><br><span class="line">    start)</span><br><span class="line">        <span class="built_in">echo</span> -n <span class="string">"Starting <span class="variable">$NAME</span>... "</span></span><br><span class="line"></span><br><span class="line">        PID=`pidof <span class="variable">$NAME</span>`</span><br><span class="line">        <span class="keyword">if</span> [ ! -z <span class="string">"<span class="variable">$PID</span>"</span> ]; <span class="keyword">then</span></span><br><span class="line">            <span class="built_in">echo</span> <span class="string">" <span class="variable">$NAME</span> already running"</span></span><br><span class="line">            <span class="built_in">exit</span> <span class="number">1</span></span><br><span class="line">        <span class="keyword">fi</span></span><br><span class="line"></span><br><span class="line">        <span class="variable">$SPAWN_FCGI</span> -u <span class="variable">$FCGI_USER</span> -g <span class="variable">$FCGI_GROUP</span> <span class="operator">-s</span> <span class="variable">$FCGI_SOCKET</span> -P <span class="variable">$PIDFILE</span> -F <span class="variable">$FORK_NUM</span> <span class="operator">-f</span> <span class="variable">$DAEMON</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> [ <span class="string">"$?"</span> != <span class="number">0</span> ]; <span class="keyword">then</span></span><br><span class="line">            <span class="built_in">echo</span> <span class="string">" failed"</span></span><br><span class="line">            <span class="built_in">exit</span> <span class="number">1</span></span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">            <span class="built_in">echo</span> <span class="string">" done"</span></span><br><span class="line">        <span class="keyword">fi</span></span><br><span class="line">    ;;</span><br><span class="line"></span><br><span class="line">    stop)</span><br><span class="line">        <span class="built_in">echo</span> -n <span class="string">"Stoping <span class="variable">$NAME</span>... "</span></span><br><span class="line"></span><br><span class="line">        PID=`pidof <span class="variable">$NAME</span>`</span><br><span class="line">        <span class="keyword">if</span> [ ! -z <span class="string">"<span class="variable">$PID</span>"</span> ]; <span class="keyword">then</span></span><br><span class="line">            <span class="built_in">kill</span> `pidof <span class="variable">$NAME</span>`</span><br><span class="line">            <span class="keyword">if</span> [ <span class="string">"$?"</span> != <span class="number">0</span> ]; <span class="keyword">then</span></span><br><span class="line">                <span class="built_in">echo</span> <span class="string">" failed. re-quit"</span></span><br><span class="line">                <span class="built_in">exit</span> <span class="number">1</span></span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">                rm <span class="operator">-f</span> <span class="variable">$pid</span></span><br><span class="line">                <span class="built_in">echo</span> <span class="string">" done"</span></span><br><span class="line">            <span class="keyword">fi</span></span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">            <span class="built_in">echo</span> <span class="string">"<span class="variable">$NAME</span> is not running."</span></span><br><span class="line">            <span class="built_in">exit</span> <span class="number">1</span></span><br><span class="line">        <span class="keyword">fi</span></span><br><span class="line">    ;;</span><br><span class="line"></span><br><span class="line">    status)</span><br><span class="line">        PID=`pidof <span class="variable">$NAME</span>`</span><br><span class="line">        <span class="keyword">if</span> [ ! -z <span class="string">"<span class="variable">$PID</span>"</span> ]; <span class="keyword">then</span></span><br><span class="line">            <span class="built_in">echo</span> <span class="string">"<span class="variable">$NAME</span> (pid <span class="variable">$PID</span>) is running..."</span></span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">            <span class="built_in">echo</span> <span class="string">"<span class="variable">$NAME</span> is stopped"</span></span><br><span class="line">            <span class="built_in">exit</span> <span class="number">0</span></span><br><span class="line">        <span class="keyword">fi</span></span><br><span class="line">    ;;</span><br><span class="line"></span><br><span class="line">    restart)</span><br><span class="line">        <span class="variable">$SCRIPTNAME</span> stop</span><br><span class="line">        sleep <span class="number">1</span></span><br><span class="line">        <span class="variable">$SCRIPTNAME</span> start</span><br><span class="line">    ;;</span><br><span class="line"></span><br><span class="line">    *)</span><br><span class="line">        <span class="built_in">echo</span> <span class="string">"Usage: <span class="variable">$SCRIPTNAME</span> &#123;start|stop|restart|status&#125;"</span></span><br><span class="line">        <span class="built_in">exit</span> <span class="number">1</span></span><br><span class="line">    ;;</span><br><span class="line"><span class="keyword">esac</span></span><br></pre></td>
    </tr>
  </table>
</figure>
<p>文件新建完成后，还需要加上执行权限，并且设置为开机自启，这样就不用每次手工去启动了</p>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td>
      <td class="code"><pre><span class="line">chmod +x /etc/init.d/fcgiwrap</span><br><span class="line">chkconfig --add fcgiwrap</span><br><span class="line">chkconfig --level <span class="number">2345</span> fcgiwrap on</span><br><span class="line">/etc/init.d/fcgiwrap start</span><br></pre></td>
    </tr>
  </table>
</figure>
<p>执行完上面的命令，就设置好自启，并将fcgiwrap的daemon进程启动好了</p>
<h2 id="Nginx"><a href="#Nginx" class="headerlink" title="Nginx"></a><strong>Nginx</strong></h2>
<p>执行CGI的环境搞好后，就差Nginx的配置了，如果将CGI的请求转发给fcgiwrap执行</p>
<figure class="highlight">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br></pre></td>
      <td class="code"><pre><span class="line">location ~ ^/cgi-bin/.*\.(cgi|sh) &#123;&#10;        gzip off;&#10;        fastcgi_pass  unix:/tmp/fcgiwrap.socket;&#10;        fastcgi_index index.cgi;&#10;        include fastcgi_params;&#10;        fastcgi_param  SCRIPT_NAME        $document_root$fastcgi_script_name;&#10;      &#125;</span><br></pre></td>
    </tr>
  </table>
</figure>
<p>我将CGI脚本放在了根目录的cgi-bin目录中，然后判断如果是.cgi或.sh结尾的文件就将请求转发给fcgiwrap执行</p>
<p>然后reload Nginx后就完成让Nginx执行CGI脚本的配置了，如果你还有perl或者Python脚本，只需要在Nginx配置中文件名后缀的判断加上对应后缀即可</p>
<p>spawn-fcgi我只启动了5个进程去执行fcgiwrap，个人使用没有啥性能问题，如果你的CGI程序访问量大，可以将进程数调高试试</p>]]></content>
    <summary type="html">
    <![CDATA[<p>由于想通过页面查看VPS使用的流量，以前用的是vnstat，非常不错的一个工具，但是几个前端插件都是需要PHP环境，但是现在将博客改用Hexo后，完全静态化，只启动了一个Nginx，不想启动php-fpm，最后找到了vnstatsvg这个项目，使用CGI的方式来获取数据，最后生成svg图片来展示，满足我的需求。</p>
<p>那问题就来了，我后端使用的是Nginx，并非Httpd，Nginx原生不支持CGI执行，之前工作上写的很多CGI都是通过Apache Httpd来执行，以前虽然看过Nginx使用fcgi执行CGI脚本的文章，但从没实践过，这次实战一次。</p>
<h2 id="spawn-fcgi"><a href="#spawn-fcgi" class="headerlink" title="spawn-fcgi"></a><strong>spawn-fcgi</strong></h2>
<p>spawn-fcgi原来是Lighttpd中的模块，现在已经独立出来，由于Nginx不能直接执行外部CGI程序，因此需要依赖spawn-fcgi来执行</p>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td>
      <td class="code"><pre><span class="line">git <span class="built_in">clone</span> git@github.com:lighttpd/spawn-fcgi.git</span><br><span class="line"><span class="built_in">cd</span> spawn-fcgi</span><br><span class="line">./autogen.sh</span><br><span class="line">./configure</span><br><span class="line">make &amp;&amp; make install</span><br></pre></td>
    </tr>
  </table>
</figure>
<p>从github获取spawn-fcgi最新代码，然后编译安装
  <br>]]>
    
    </summary>
    
      <category term="CGI" scheme="http://xfeng.me/tags/cgi/"/>
    
      <category term="Nginx" scheme="http://xfeng.me/tags/nginx/"/>
    
      <category term="apache" scheme="http://xfeng.me/tags/apache/"/>
    
      <category term="fastcgi" scheme="http://xfeng.me/tags/fastcgi/"/>
    
      <category term="httpd" scheme="http://xfeng.me/tags/httpd/"/>
    
      <category term="Linux" scheme="http://xfeng.me/category/linux/"/>
    
      <category term="Nginx" scheme="http://xfeng.me/category/linux/nginx/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[图床从yupoo迁移到upyun]]></title>
    <link href="http://xfeng.me/yupoo-transfer-to-upyun/"/>
    <id>http://xfeng.me/yupoo-transfer-to-upyun/</id>
    <published>2014-11-11T06:11:11.000Z</published>
    <updated>2015-12-25T04:05:44.000Z</updated>
    <content type="html"><![CDATA[<h2 id="u524D_u8A00"><a href="#u524D_u8A00" class="headerlink" title="前言"></a><strong>前言</strong></h2>
<p>前段时间yupoo的vip到期了，用yupoo用了三四年vip了吧，每年60也不贵，我流量不多，每个月2g左右，现在yupoo推出了upyun，加入联盟还能每个月15G免费流量，所以准备切换到upyun</p>
<p>upyun刚推出测试的时候，我参与试用过，不过基本没用，现在看发现那个帐号被冻结了，客服说再注册一个好了</p>
<h2 id="u8FC1_u79FB"><a href="#u8FC1_u79FB" class="headerlink" title="迁移"></a><strong>迁移</strong></h2>
<p>重新注册申请加入联盟，客服响应速度非常快</p>
<h3 id="u8FC1_u79FB_u56FE_u7247"><a href="#u8FC1_u79FB_u56FE_u7247" class="headerlink" title="迁移图片"></a><strong>迁移图片</strong></h3>
<p>注册完成后，就是要把原来yupoo的图片都迁移过来，这里真后悔vip要到期的时候怎么不赶紧用ftp把图片备份出来，现在vip过期了，不可能手工去保存所有图片，上千张的，无奈只好又开了一次最便宜的个人vip
  <br>
  <a id="more"></a>
  <br>然后通过vip的备份功能把图片备份到upyun创建的新bucket中，这里需要注意的是，创建的空间必须选文件，我开始创建了图片空间，因为想着yupoo都是图片，结果一直失败，后面咨询客服才知道必须要文件格式</p>
<p>换了文件空间后，图片很快备份好了</p>
<h3 id="u6587_u4EF6_u6539_u540D"><a href="#u6587_u4EF6_u6539_u540D" class="headerlink" title="文件改名"></a><strong>文件改名</strong></h3>
<p>通过ftp备份出来的图片是按上传时间放在对应目录里，例如2013/08/23/xxx.jpg，由于更换到upyun后，图片url会变更了，如果还要找到图片在哪个时间目录里很麻烦，可以写个脚本去扫文章中图片连接然后查找目录后替换，但是懒人不想那么麻烦</p>
<p>因此先把所有图片移动到根目录
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line">find . -type f -exec mv \-fv &#123;&#125; . \;</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>然后yupoo的图片名字是用户名+随机字符串+字符串构成的，例如zyxfsky_Dktsyts_xfntsg.jpg，看了我的图片第一个随机字符串已经是唯一的了，而且我以前很多图片使用的不是原图，而是中型图，连接例如<code>http://pic.yupoo.com/zyxfsky/Dktsyts/medium.jpg</code></p>
<p>这里如果要完整替换也要写脚本去查找到第二个随机字符串进行替换，但懒人觉得第一个已经是唯一的了，直接丢弃第二个更省事，将图片全部改名
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> `ls`;<span class="keyword">do</span> name=`<span class="built_in">echo</span> <span class="variable">$i</span>|awk -F\_ <span class="string">'&#123;print $2&#125;'</span>`;fix=`<span class="built_in">echo</span> <span class="variable">$i</span>|awk -F\. <span class="string">'&#123;print $2&#125;'</span>`;mv -v <span class="variable">$i</span> <span class="string">"<span class="variable">$name</span>.<span class="variable">$fix</span>"</span>;<span class="keyword">done</span></span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>最后图片名字为Dktsyts.jgp</p>
<h3 id="u4E0A_u4F20_u56FE_u7247"><a href="#u4E0A_u4F20_u56FE_u7247" class="headerlink" title="上传图片"></a><strong>上传图片</strong></h3>
<p>图片改名好后，在upyun新建一个图片空间，图片空间可以创建微缩图，将图片上传到新空间</p>
<p>然后新建一个自定义版本，设置好需要的自适应宽度，例如我的样式为medium</p>
<p>然后空间绑定域名，必须是备案的域名，我的xfeng.me没有备案，前段时间找公司办理备案，各种曲折</p>
<p>因为我08年joysboy.net备案过，现在备案个人不能提交申请了，要IDC提交，但是需要我原来的个人密码，我早忘记了，然后里面的手机号码也是很早以前已经没用的号码，找回密码没法收到短信，要想改手机号得找原来的接入商，那接入商估计早倒闭没在了，想注销原来的备案重新备，也得找原来接入商注销。。。。最后放弃了</p>
<p>只要绑定img.xfeng.me，审核速度也非常快，一分钟就ok</p>
<h3 id="u66FF_u6362_u6587_u7AE0_u56FE_u7247URL"><a href="#u66FF_u6362_u6587_u7AE0_u56FE_u7247URL" class="headerlink" title="替换文章图片URL"></a><strong>替换文章图片URL</strong></h3>
<p>图片上传完成后，新图片的URL变成<code>http://img.xfeng.me/Dktsyts.jpg</code>,原来文章中的图片地址是<code>http://pic.yupoo.com/zyxfsky/Dktsyts/medium.jpg</code>，接下来就是把这些URL全部替换
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> `ls`;<span class="keyword">do</span> sed -i <span class="string">'s/pic\.yupoo\.com\/zyxfsky\/\([^\/]*\)\/[^\.]*\.\([^(\)| )]*\)/img.xfeng.me\/\1\.\2!medium/g'</span> <span class="variable">$i</span>;<span class="keyword">done</span></span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>替换完成后URL变成<code>http://img.xfeng.me/Dktsyts.jpg!medium</code></p>
<p>最后的!medium是自定义版本，也就是微缩图</p>
<h3 id="u91CD_u65B0_u90E8_u7F72"><a href="#u91CD_u65B0_u90E8_u7F72" class="headerlink" title="重新部署"></a><strong>重新部署</strong></h3>
<p>确认图片地址全部替换无误后，重新生成html发布
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line">hexo clean;hexo deploy -g</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<h2 id="u5FC3_u5F97"><a href="#u5FC3_u5F97" class="headerlink" title="心得"></a><strong>心得</strong></h2>
<p>从图片加载时间来看，upyun比yupoo图片管家速度快，估计是CDN节点更多的原因</p>
<p>加上现在免费流量和空间，非常推荐使用upyun，整个迁移过程如果去掉上传和下载图片的耗时，就几分钟</p>
<p>另外我还建了一个文件空间，把js和css也放到upyun了，现在只有一个html从我那破vps获取了</p>]]></content>
    <summary type="html">
    <![CDATA[<h2 id="u524D_u8A00"><a href="#u524D_u8A00" class="headerlink" title="前言"></a><strong>前言</strong></h2>
<p>前段时间yupoo的vip到期了，用yupoo用了三四年vip了吧，每年60也不贵，我流量不多，每个月2g左右，现在yupoo推出了upyun，加入联盟还能每个月15G免费流量，所以准备切换到upyun</p>
<p>upyun刚推出测试的时候，我参与试用过，不过基本没用，现在看发现那个帐号被冻结了，客服说再注册一个好了</p>
<h2 id="u8FC1_u79FB"><a href="#u8FC1_u79FB" class="headerlink" title="迁移"></a><strong>迁移</strong></h2>
<p>重新注册申请加入联盟，客服响应速度非常快</p>
<h3 id="u8FC1_u79FB_u56FE_u7247"><a href="#u8FC1_u79FB_u56FE_u7247" class="headerlink" title="迁移图片"></a><strong>迁移图片</strong></h3>
<p>注册完成后，就是要把原来yupoo的图片都迁移过来，这里真后悔vip要到期的时候怎么不赶紧用ftp把图片备份出来，现在vip过期了，不可能手工去保存所有图片，上千张的，无奈只好又开了一次最便宜的个人vip
  <br>]]>
    
    </summary>
    
      <category term="cdn" scheme="http://xfeng.me/tags/cdn/"/>
    
      <category term="upyun" scheme="http://xfeng.me/tags/upyun/"/>
    
      <category term="yupoo" scheme="http://xfeng.me/tags/yupoo/"/>
    
      <category term="Web Share" scheme="http://xfeng.me/category/web-share/"/>
    
      <category term="Interesting" scheme="http://xfeng.me/category/web-share/interesting/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[Perl查询svn分支版本、修改时间等信息]]></title>
    <link href="http://xfeng.me/get-svn-info-perl/"/>
    <id>http://xfeng.me/get-svn-info-perl/</id>
    <published>2014-08-23T08:35:35.000Z</published>
    <updated>2015-12-25T04:05:44.000Z</updated>
    <content type="html"><![CDATA[<p>查询分支的版本，最后修改时间，最新tag等信息的方法</p>
<p>函数以类的私有函数的方式定义，可以改为正常函数使用，如果查询失败会自动重试，连续两次都失败后终止</p>
<p>先定义下全局的svn参数，以及依赖的lib</p>
<figure class="highlight perl">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td>
      <td class="code"><pre><span class="line"><span class="keyword">use</span> XML::Simple;</span><br><span class="line"><span class="keyword">my</span> <span class="variable">$svn_args</span> = <span class="string">"--username xxx --password yyy --no-auth-cache --non-interactive"</span>;</span><br></pre></td>
    </tr>
  </table>
</figure>
<h3 id="u67E5_u8BE2svn_u5206_u652F_u6700_u65B0_u7248_u672C"><a href="#u67E5_u8BE2svn_u5206_u652F_u6700_u65B0_u7248_u672C" class="headerlink" title="查询svn分支最新版本"></a>查询svn分支最新版本</h3>
<p>入参：分支URL
  <br>返回值：查询成功返回版本号，失败返回undef
  <br>
  <figure class="highlight perl">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td>
        <td class="code"><pre><span class="line"><span class="keyword">my</span> <span class="variable">$get_svnVer</span> = <span class="sub"><span class="keyword">sub</span> &#123;</span></span><br><span class="line">    <span class="keyword">my</span> (<span class="variable">$branch</span>, <span class="variable">$fail_num</span>) = <span class="variable">@_</span>;</span><br><span class="line">    <span class="keyword">chomp</span> <span class="variable">$branch</span>;</span><br><span class="line">    <span class="keyword">if</span> (!<span class="variable">$fail_num</span>) &#123;</span><br><span class="line">        <span class="variable">$fail_num</span> = <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="variable">$fail_num</span> += <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$fail_num</span> &gt; <span class="number">2</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">undef</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">my</span> <span class="variable">$result</span> = <span class="string">`svn info $svn_args --xml $branch 2&gt;/dev/null`</span>;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$?</span> == <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">my</span> <span class="variable">$xml</span>  = XML::Simple-&gt;new();</span><br><span class="line">        <span class="keyword">my</span> <span class="variable">$data</span> = <span class="variable">$xml</span>-&gt;XMLin(<span class="variable">$result</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="variable">$data</span>-&gt;&#123;<span class="string">'entry'</span>&#125;-&gt;&#123;<span class="string">'commit'</span>&#125;-&gt;&#123;<span class="string">'revision'</span>&#125;;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="variable">$get_svnVer</span>-&gt;(<span class="variable">$branch</span>, <span class="variable">$fail_num</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<a id="more"></a>
<h3 id="u67E5_u8BE2svn_u5206_u652F_u6700_u540E_u4FEE_u6539_u65F6_u95F4"><a href="#u67E5_u8BE2svn_u5206_u652F_u6700_u540E_u4FEE_u6539_u65F6_u95F4" class="headerlink" title="查询svn分支最后修改时间"></a>查询svn分支最后修改时间</h3>
<p>入参：分支URL
  <br>返回值：查询失败返回undef，成功返回时间字符串，exp:20140821130515
  <br>
  <figure class="highlight perl">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td>
        <td class="code"><pre><span class="line"><span class="keyword">my</span> <span class="variable">$get_last_mtime</span> = <span class="sub"><span class="keyword">sub</span> &#123;</span></span><br><span class="line">    <span class="keyword">my</span> (<span class="variable">$branch</span>, <span class="variable">$fail_num</span>) = <span class="variable">@_</span>;</span><br><span class="line">    <span class="keyword">chomp</span> <span class="variable">$branch</span>;</span><br><span class="line">    <span class="keyword">if</span> (!<span class="variable">$fail_num</span>) &#123;</span><br><span class="line">        <span class="variable">$fail_num</span> = <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="variable">$fail_num</span> += <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$fail_num</span> &gt; <span class="number">2</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">undef</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">my</span> <span class="variable">$result</span> = <span class="string">`svn info $svn_args --xml $branch 2&gt;/dev/null`</span>;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$?</span> == <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">my</span> <span class="variable">$xml</span>  = XML::Simple-&gt;new();</span><br><span class="line">        <span class="keyword">my</span> <span class="variable">$data</span> = <span class="variable">$xml</span>-&gt;XMLin(<span class="variable">$result</span>);</span><br><span class="line">        <span class="keyword">my</span> <span class="variable">$time</span> = <span class="variable">$data</span>-&gt;&#123;<span class="string">'entry'</span>&#125;-&gt;&#123;<span class="string">'commit'</span>&#125;-&gt;&#123;<span class="string">'date'</span>&#125;;</span><br><span class="line">        <span class="variable">$time</span> =~ <span class="regexp">/(\d&#123;4&#125;)\-(\d&#123;2&#125;)\-(\d&#123;2&#125;)T(\d&#123;2&#125;)\:(\d&#123;2&#125;)\:(\d&#123;2&#125;)\..*/</span>;</span><br><span class="line">        <span class="keyword">return</span> <span class="variable">$1</span> . <span class="variable">$2</span> . <span class="variable">$3</span> . <span class="variable">$4</span> . <span class="variable">$5</span> . <span class="variable">$6</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="variable">$get_last_mtime</span>-&gt;(<span class="variable">$branch</span>, <span class="variable">$fail_num</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<h3 id="u67E5_u8BE2_u6700_u65B0tag"><a href="#u67E5_u8BE2_u6700_u65B0tag" class="headerlink" title="查询最新tag"></a>查询最新tag</h3>
<p>如果tag也是创建在根路径tags目录适用</p>
<p>入参：仓库任意分支URL，需要忽略的tag名(可选)
  <br>返回值：查询成功返回tag URL，失败返回undef
  <br>
  <figure class="highlight perl">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td>
        <td class="code"><pre><span class="line"><span class="keyword">my</span> <span class="variable">$get_last_tag</span> = <span class="sub"><span class="keyword">sub</span> &#123;</span></span><br><span class="line">    <span class="keyword">my</span> (<span class="variable">$branch</span>, <span class="variable">$ignoreid</span>, <span class="variable">$fail_num</span>) = <span class="variable">@_</span>;</span><br><span class="line">    <span class="keyword">chomp</span> <span class="variable">$branch</span>;</span><br><span class="line">    <span class="keyword">if</span> (!<span class="variable">$fail_num</span>) &#123;</span><br><span class="line">        <span class="variable">$fail_num</span> = <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="variable">$fail_num</span> += <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$fail_num</span> &gt; <span class="number">3</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">undef</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">my</span> <span class="variable">$result</span> = <span class="string">`svn info $svn_args --xml $branch 2&gt;/dev/null`</span>;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$?</span> == <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">my</span> <span class="variable">$xml</span>       = XML::Simple-&gt;new();</span><br><span class="line">        <span class="keyword">my</span> <span class="variable">$data</span>      = <span class="variable">$xml</span>-&gt;XMLin(<span class="variable">$result</span>);</span><br><span class="line">        <span class="keyword">my</span> <span class="variable">$repo_root</span> = <span class="variable">$data</span>-&gt;&#123;<span class="string">'entry'</span>&#125;-&gt;&#123;<span class="string">'repository'</span>&#125;-&gt;&#123;<span class="string">'root'</span>&#125;;</span><br><span class="line">        <span class="keyword">my</span> <span class="variable">$num</span>       = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">my</span> <span class="variable">$last_tag</span>;</span><br><span class="line">        <span class="keyword">while</span> (!<span class="variable">$last_tag</span>) &#123;</span><br><span class="line">            <span class="keyword">my</span> <span class="variable">$result_log</span> = <span class="string">`svn log -l$num -v --stop-on-copy --xml $svn_args $repo_root/tags 2&gt;/dev/null`</span>;</span><br><span class="line">            <span class="keyword">if</span> (<span class="variable">$?</span> == <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="keyword">my</span> <span class="variable">$xml_log</span>  = XML::Simple-&gt;new();</span><br><span class="line">                <span class="keyword">my</span> <span class="variable">$data_log</span> = <span class="variable">$xml_log</span>-&gt;XMLin(<span class="variable">$result_log</span>);</span><br><span class="line">                <span class="keyword">my</span> <span class="variable">@logs</span>;</span><br><span class="line">                <span class="comment">#如果limit 1时返回的logentry不是数组，数组赋值异常后将值push到数组</span></span><br><span class="line">                <span class="keyword">eval</span> &#123; <span class="variable">@logs</span> = @&#123; <span class="variable">$data_log</span>-&gt;&#123;<span class="string">'logentry'</span>&#125; &#125;; &#125;;</span><br><span class="line">                <span class="keyword">if</span> (<span class="variable">$@</span>) &#123;</span><br><span class="line">                    <span class="keyword">push</span> <span class="variable">@logs</span>, <span class="variable">$data_log</span>-&gt;&#123;<span class="string">'logentry'</span>&#125;;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span> (<span class="variable">$logs</span>[ <span class="variable">$num</span> - <span class="number">1</span> ]-&gt;&#123;<span class="string">'revision'</span>&#125; == <span class="number">1</span>) &#123;</span><br><span class="line">                    <span class="keyword">return</span> <span class="keyword">undef</span>;</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="keyword">if</span> (<span class="variable">$logs</span>[ <span class="variable">$num</span> - <span class="number">1</span> ]-&gt;&#123;<span class="string">'paths'</span>&#125;-&gt;&#123;<span class="string">'path'</span>&#125;-&gt;&#123;<span class="string">'action'</span>&#125; eq <span class="string">"A"</span>) &#123;</span><br><span class="line">                    <span class="keyword">my</span> <span class="variable">$tag_name</span> = <span class="variable">$logs</span>[ <span class="variable">$num</span> - <span class="number">1</span> ]-&gt;&#123;<span class="string">'paths'</span>&#125;-&gt;&#123;<span class="string">'path'</span>&#125;-&gt;&#123;<span class="string">'content'</span>&#125;;</span><br><span class="line">                    <span class="keyword">my</span> <span class="variable">$tag_ver</span>  = <span class="variable">$logs</span>[ <span class="variable">$num</span> - <span class="number">1</span> ]-&gt;&#123;<span class="string">'revision'</span>&#125;;</span><br><span class="line">                    <span class="keyword">if</span> (<span class="variable">$ignoreid</span>) &#123;</span><br><span class="line">                        <span class="keyword">if</span> (<span class="variable">$tag_name</span> !~ <span class="regexp">/$ignoreid/</span>) &#123;</span><br><span class="line">                            <span class="keyword">system</span>(<span class="string">"svn list <span class="variable">$svn_args</span> <span class="variable">$repo_root</span><span class="variable">$tag_name</span> &gt;/dev/null 2&gt;&amp;1"</span>);</span><br><span class="line">                            <span class="keyword">if</span> (<span class="variable">$?</span> == <span class="number">0</span>) &#123;</span><br><span class="line">                                <span class="variable">$last_tag</span> = <span class="variable">$tag_name</span> . <span class="string">"\@"</span> . <span class="variable">$tag_ver</span>;</span><br><span class="line">                                <span class="keyword">last</span>;</span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="keyword">else</span> &#123;</span><br><span class="line">                        <span class="keyword">system</span>(<span class="string">"svn list <span class="variable">$svn_args</span> <span class="variable">$repo_root</span><span class="variable">$tag_name</span> &gt;/dev/null 2&gt;&amp;1"</span>);</span><br><span class="line">                        <span class="keyword">if</span> (<span class="variable">$?</span> == <span class="number">0</span>) &#123;</span><br><span class="line">                            <span class="variable">$last_tag</span> = <span class="variable">$tag_name</span> . <span class="string">"\@"</span> . <span class="variable">$tag_ver</span>;</span><br><span class="line">                            <span class="keyword">last</span>;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="variable">$get_last_tag</span>-&gt;(<span class="variable">$branch</span>, <span class="variable">$ignoreid</span>, <span class="variable">$fail_num</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="variable">$num</span>++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="variable">$repo_root</span> . <span class="variable">$last_tag</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="variable">$get_last_tag</span>-&gt;(<span class="variable">$branch</span>, <span class="variable">$ignoreid</span>, <span class="variable">$fail_num</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>调用方法：
  <br>
  <figure class="highlight perl">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td>
        <td class="code"><pre><span class="line"><span class="keyword">my</span> <span class="variable">$ver</span> = <span class="variable">$get_svnVer</span>-&gt;(<span class="variable">$url</span>);</span><br><span class="line"><span class="comment">#如果作为类函数调用，入参改为</span></span><br><span class="line"><span class="comment">#   my ($self, $branch, $fail_num) = @_;</span></span><br><span class="line"><span class="keyword">my</span> <span class="variable">$ver</span> = <span class="variable">$self</span>-&gt;<span class="variable">$get_svnVer</span>(<span class="variable">$url</span>);</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>]]></content>
    <summary type="html">
    <![CDATA[<p>查询分支的版本，最后修改时间，最新tag等信息的方法</p>
<p>函数以类的私有函数的方式定义，可以改为正常函数使用，如果查询失败会自动重试，连续两次都失败后终止</p>
<p>先定义下全局的svn参数，以及依赖的lib</p>
<figure class="highlight perl">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td>
      <td class="code"><pre><span class="line"><span class="keyword">use</span> XML::Simple;</span><br><span class="line"><span class="keyword">my</span> <span class="variable">$svn_args</span> = <span class="string">"--username xxx --password yyy --no-auth-cache --non-interactive"</span>;</span><br></pre></td>
    </tr>
  </table>
</figure>
<h3 id="u67E5_u8BE2svn_u5206_u652F_u6700_u65B0_u7248_u672C"><a href="#u67E5_u8BE2svn_u5206_u652F_u6700_u65B0_u7248_u672C" class="headerlink" title="查询svn分支最新版本"></a>查询svn分支最新版本</h3>
<p>入参：分支URL
  <br>返回值：查询成功返回版本号，失败返回undef
  <br>
  <figure class="highlight perl">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td>
        <td
        class="code"><pre><span class="line"><span class="keyword">my</span> <span class="variable">$get_svnVer</span> = <span class="sub"><span class="keyword">sub</span> &#123;</span></span><br><span class="line">    <span class="keyword">my</span> (<span class="variable">$branch</span>, <span class="variable">$fail_num</span>) = <span class="variable">@_</span>;</span><br><span class="line">    <span class="keyword">chomp</span> <span class="variable">$branch</span>;</span><br><span class="line">    <span class="keyword">if</span> (!<span class="variable">$fail_num</span>) &#123;</span><br><span class="line">        <span class="variable">$fail_num</span> = <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="variable">$fail_num</span> += <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$fail_num</span> &gt; <span class="number">2</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">undef</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">my</span> <span class="variable">$result</span> = <span class="string">`svn info $svn_args --xml $branch 2&gt;/dev/null`</span>;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$?</span> == <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">my</span> <span class="variable">$xml</span>  = XML::Simple-&gt;new();</span><br><span class="line">        <span class="keyword">my</span> <span class="variable">$data</span> = <span class="variable">$xml</span>-&gt;XMLin(<span class="variable">$result</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="variable">$data</span>-&gt;&#123;<span class="string">'entry'</span>&#125;-&gt;&#123;<span class="string">'commit'</span>&#125;-&gt;&#123;<span class="string">'revision'</span>&#125;;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="variable">$get_svnVer</span>-&gt;(<span class="variable">$branch</span>, <span class="variable">$fail_num</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>]]>
    
    </summary>
    
      <category term="perl" scheme="http://xfeng.me/tags/perl/"/>
    
      <category term="svn" scheme="http://xfeng.me/tags/svn/"/>
    
      <category term="Develop" scheme="http://xfeng.me/category/develop/"/>
    
      <category term="Perl" scheme="http://xfeng.me/category/develop/perl/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[使用GA事件跟踪Baidu分享效果]]></title>
    <link href="http://xfeng.me/google-analytics-event-track-baidu-share/"/>
    <id>http://xfeng.me/google-analytics-event-track-baidu-share/</id>
    <published>2014-08-21T02:51:43.000Z</published>
    <updated>2015-12-25T04:05:44.000Z</updated>
    <content type="html"><![CDATA[<p>更换Hexo后，试用了下Baidu分享，感觉加载速度比jiathis快，抛弃了jiathis，新版的Baidu分享也提供了自定义函数，可以加上事件监控，把分享数据统计到Google Analytics中</p>
<p>Baidu分享代码中，在_bd_share_config配置信息里，common配置中onAfterClick可以定义一个点击分享后触发执行的函数</p>
<p>因此先定义一个soctrack函数，入参是baidu分享的cmd，就是分享按钮的名字，函数功能是向Google analytics发送一个事件消息，如果你使用Baidu统计，也可以向百度发送一个事件</p>
<p>函数定义好以后，在Baidu分享config的common.onAfterClick中引用这个函数即可
  <br>
  <figure class="highlight javascript">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td>
        <td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">soctrack</span>(<span class="params">cmd</span>)</span>&#123;ga(<span class="string">'send'</span>, <span class="string">'social'</span>, cmd, <span class="string">'BaiduShare'</span>, _bd_share_config.common.bdUrl);&#125;;</span><br><span class="line"><span class="built_in">window</span>._bd_share_config=&#123;</span><br><span class="line">  <span class="string">"common"</span>: &#123;</span><br><span class="line">    <span class="string">"bdMini"</span>: <span class="string">"3"</span>,</span><br><span class="line">    <span class="string">"bdSnsKey"</span>: &#123;&#125;,</span><br><span class="line">    <span class="string">"bdText"</span>: <span class="string">""</span>,</span><br><span class="line">    <span class="string">"bdMiniList"</span>: [],</span><br><span class="line">    <span class="string">"bdPic"</span>: <span class="string">""</span>,</span><br><span class="line">    <span class="string">"onAfterClick"</span>: soctrack</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="string">"share"</span>: &#123;&#125;,</span><br><span class="line">  <span class="string">"image"</span>: &#123;</span><br><span class="line">    <span class="string">"viewList"</span>: [],</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="string">"selectShare"</span>: &#123;</span><br><span class="line">    <span class="string">"bdContainerClass"</span>: <span class="string">"article-entry"</span>,</span><br><span class="line">    <span class="string">"bdSelectMiniList"</span>: []</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">with</span>(<span class="built_in">document</span>)<span class="number">0</span>[(getElementsByTagName(<span class="string">'head'</span>)[<span class="number">0</span>]||body).appendChild(createElement(<span class="string">'script'</span>)).src=<span class="string">'http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='</span>+~(-<span class="keyword">new</span> <span class="built_in">Date</span>()/<span class="number">36e5</span>)];</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<a id="more"></a>
<p>上面的例子里，Google Analytics使用的是新版的统计代码，如果你还在使用老版ga.js的话，可以改为下面代码
  <br>
  <figure class="highlight javascript">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">soctrack</span>(<span class="params">cmd</span>)</span>&#123;_gaq.push([<span class="string">'_trackEvent'</span>, cmd, <span class="string">'BaiduShare'</span>, _bd_share_config.common.bdUrl]);&#125;;</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>如果你使用Baidu统计，改为下面代码
  <br>
  <figure class="highlight javascript">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">soctrack</span>(<span class="params">cmd</span>)</span>&#123;_hmt.push([<span class="string">'_trackEvent'</span>, cmd, <span class="string">'BaiduShare'</span>, _bd_share_config.common.bdUrl]);&#125;;</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>有没有发现百度抄袭Google Analytics抄的好猛</p>
<p>如果你百度和Google一起使用，两段代码都放进去也可以
  <br>
  <figure class="highlight javascript">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td>
        <td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">soctrack</span>(<span class="params">cmd</span>)</span>&#123;</span><br><span class="line">  ga(<span class="string">'send'</span>, <span class="string">'social'</span>, cmd, <span class="string">'Share'</span>, baidu_share.common.bdUrl);</span><br><span class="line">  _hmt.push([<span class="string">'_trackEvent'</span>, cmd, <span class="string">'BaiduShare'</span>, _bd_share_config.common.bdUrl]);</span><br><span class="line">&#125;;</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>可以通过firebug看到具体的信息
  <br><img src="http://img.xfeng.me/yupoo/DZWZXMVg.jpg!medium" alt="" title="baidu analytics">
  <br>已经把这个信息push出去了，你还可以搞这个功能增加用户的属性，或者增加积分等等</p>]]></content>
    <summary type="html">
    <![CDATA[<p>更换Hexo后，试用了下Baidu分享，感觉加载速度比jiathis快，抛弃了jiathis，新版的Baidu分享也提供了自定义函数，可以加上事件监控，把分享数据统计到Google Analytics中</p>
<p>Baidu分享代码中，在_bd_share_config配置信息里，common配置中onAfterClick可以定义一个点击分享后触发执行的函数</p>
<p>因此先定义一个soctrack函数，入参是baidu分享的cmd，就是分享按钮的名字，函数功能是向Google analytics发送一个事件消息，如果你使用Baidu统计，也可以向百度发送一个事件</p>
<p>函数定义好以后，在Baidu分享config的common.onAfterClick中引用这个函数即可
  <br>
  <figure class="highlight javascript">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td>
        <td
        class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">soctrack</span>(<span class="params">cmd</span>)</span>&#123;ga(<span class="string">'send'</span>, <span class="string">'social'</span>, cmd, <span class="string">'BaiduShare'</span>, _bd_share_config.common.bdUrl);&#125;;</span><br><span class="line"><span class="built_in">window</span>._bd_share_config=&#123;</span><br><span class="line">  <span class="string">"common"</span>: &#123;</span><br><span class="line">    <span class="string">"bdMini"</span>: <span class="string">"3"</span>,</span><br><span class="line">    <span class="string">"bdSnsKey"</span>: &#123;&#125;,</span><br><span class="line">    <span class="string">"bdText"</span>: <span class="string">""</span>,</span><br><span class="line">    <span class="string">"bdMiniList"</span>: [],</span><br><span class="line">    <span class="string">"bdPic"</span>: <span class="string">""</span>,</span><br><span class="line">    <span class="string">"onAfterClick"</span>: soctrack</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="string">"share"</span>: &#123;&#125;,</span><br><span class="line">  <span class="string">"image"</span>: &#123;</span><br><span class="line">    <span class="string">"viewList"</span>: [],</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="string">"selectShare"</span>: &#123;</span><br><span class="line">    <span class="string">"bdContainerClass"</span>: <span class="string">"article-entry"</span>,</span><br><span class="line">    <span class="string">"bdSelectMiniList"</span>: []</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">with</span>(<span class="built_in">document</span>)<span class="number">0</span>[(getElementsByTagName(<span class="string">'head'</span>)[<span class="number">0</span>]||body).appendChild(createElement(<span class="string">'script'</span>)).src=<span class="string">'http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='</span>+~(-<span class="keyword">new</span> <span class="built_in">Date</span>()/<span class="number">36e5</span>)];</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>]]>
    
    </summary>
    
      <category term="analytics" scheme="http://xfeng.me/tags/analytics/"/>
    
      <category term="baidu" scheme="http://xfeng.me/tags/baidu/"/>
    
      <category term="google" scheme="http://xfeng.me/tags/google/"/>
    
      <category term="js" scheme="http://xfeng.me/tags/js/"/>
    
      <category term="Web Share" scheme="http://xfeng.me/category/web-share/"/>
    
      <category term="wordpress" scheme="http://xfeng.me/category/web-share/wordpress/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[sublimetext格式化bash插件]]></title>
    <link href="http://xfeng.me/sublime-text-plugin-pretty-bash/"/>
    <id>http://xfeng.me/sublime-text-plugin-pretty-bash/</id>
    <published>2014-08-07T06:06:45.000Z</published>
    <updated>2015-12-25T04:05:44.000Z</updated>
    <content type="html"><![CDATA[<p><a href="https://github.com/joysboy/SublimeBashTidy" target="_blank" rel="external">SublimeBashTidy</a></p>
<p>一直很喜欢Sublime Text，也有非常多的插件，对于Coder来说，代码规范看着就会觉得赏心悦目，所以很喜欢那些tidy的插件，可以自动将代码格式化，但是没有找到bash的tidy插件</p>
<p>做运维的bash绝对不会少写，一些简单的脚本可以直接在一行命令里搞定，但是比较复杂的，还是喜欢在编辑器里写，没有tidy插件让我很不爽，最后忍不住自己去写一个插件</p>
<p>自己完整的写一套bash的格式化逻辑还是有点折腾的，于是在github上搜有没有类似的project，找到了<a href="https://github.com/ewiger/beautify_bash" target="_blank" rel="external">beautify_bash</a>，也是Python的project，这就简单了</p>
<p>Sublime text也是Python开发的，提供了Python的API，找了下其他tidy插件的写法，格式化代码只需要调用API获取文件内容或者选中区域内容，然后将获取到字符串处理完，再次调用API把处理完的内容替换掉原来的内容</p>
<h2 id="Dev"><a href="#Dev" class="headerlink" title="Dev"></a>Dev</h2>
<p>简单的文本处理插件只需要创建一个sublime_plugin.TextCommand类，类名叫XXCommand就行
  <br>
  <a id="more"></a>
  <br>原本想吧beautify_bash作为submodule加到git库里，但是submodule总是有一堆问题，最后还是选择把beautify_bash的func直接引用到插件代码里，readme里说明了来源，beauatify_bash也没有说没使用什么协议共享，放在github public project里，应该不侵权</p>
<figure class="highlight python">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br></pre></td>
      <td class="code"><pre><span class="line">sublime.Region(<span class="number">0</span>, self.view.size())</span><br></pre></td>
    </tr>
  </table>
</figure>
<p>通过上面代码获取到文件内容，然后把格式化后的文本通过下面方法替换原文件的内容
  <br>
  <figure class="highlight python">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td>
        <td class="code"><pre><span class="line">self.view.replace(</span><br><span class="line">            edit, xmlRegion, result.replace(<span class="string">"\r"</span>, <span class="string">""</span>))</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>然后在touch一个sublime-keymap来定义快捷键，command就是类名XXCommand中的XX
  <br>
  <figure class="highlight json">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td>
        <td class="code"><pre><span class="line">[</span><br><span class="line">    &#123;</span><br><span class="line">        "<span class="attribute">keys</span>": <span class="value">[<span class="string">"super+shift+alt+b"</span>]</span>,</span><br><span class="line">        "<span class="attribute">command</span>": <span class="value"><span class="string">"bashtidy"</span></span><br><span class="line">    </span>&#125;</span><br><span class="line">]</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>一个简单的插件就这么完成了，比我想象的简单，sublime text提供的API非常方便</p>
<h2 id="u4F7F_u7528_u65B9_u6CD5"><a href="#u4F7F_u7528_u65B9_u6CD5" class="headerlink" title="使用方法"></a>使用方法</h2>
<p>打开Sublime Text的Package文件夹</p>
<ul>
  <li>OS X: ~/Library/Application Support/Sublime Text (2/3)/Packages/</li>
  <li>Windows: %APPDATA%/Sublime Text (2/3)/Packages/</li>
  <li>Linux: ~/.Sublime Text (2/3)/Packages/</li>
</ul>
<p>将插件clone到Package目录，插件repo地址如下：
  <br>
  <figure class="highlight groovy">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line"><span class="string">https:</span><span class="comment">//github.com/joysboy/SublimeBashTidy.git</span></span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>安装完成后，可以通过右键菜单里选择Prettify Bash对代码格式化</p>
<p>或者通过ctrl + shift + P调出命令窗口，输入bashtidy对代码格式化</p>
<p>还可以通过快捷键调用</p>
<ul>
  <li>OSX: super + shift + alt + b</li>
  <li>Win: ctrl + shift + alt + b</li>
  <li>Linux: ctrl + shift + alt + b</li>
</ul>
<p>如果使用有问题或者建议欢迎留言</p>]]></content>
    <summary type="html">
    <![CDATA[<p><a href="https://github.com/joysboy/SublimeBashTidy">SublimeBashTidy</a></p>
<p>一直很喜欢Sublime Text，也有非常多的插件，对于Coder来说，代码规范看着就会觉得赏心悦目，所以很喜欢那些tidy的插件，可以自动将代码格式化，但是没有找到bash的tidy插件</p>
<p>做运维的bash绝对不会少写，一些简单的脚本可以直接在一行命令里搞定，但是比较复杂的，还是喜欢在编辑器里写，没有tidy插件让我很不爽，最后忍不住自己去写一个插件</p>
<p>自己完整的写一套bash的格式化逻辑还是有点折腾的，于是在github上搜有没有类似的project，找到了<a href="https://github.com/ewiger/beautify_bash">beautify_bash</a>，也是Python的project，这就简单了</p>
<p>Sublime text也是Python开发的，提供了Python的API，找了下其他tidy插件的写法，格式化代码只需要调用API获取文件内容或者选中区域内容，然后将获取到字符串处理完，再次调用API把处理完的内容替换掉原来的内容</p>
<h2 id="Dev"><a href="#Dev" class="headerlink" title="Dev"></a>Dev</h2>
<p>简单的文本处理插件只需要创建一个sublime_plugin.TextCommand类，类名叫XXCommand就行
  <br>]]>
    
    </summary>
    
      <category term="bash" scheme="http://xfeng.me/tags/bash/"/>
    
      <category term="plugin" scheme="http://xfeng.me/tags/plugin/"/>
    
      <category term="python" scheme="http://xfeng.me/tags/python/"/>
    
      <category term="sublimetext" scheme="http://xfeng.me/tags/sublimetext/"/>
    
      <category term="Develop" scheme="http://xfeng.me/category/develop/"/>
    
      <category term="Python" scheme="http://xfeng.me/category/develop/python/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[更换博客到Hexo]]></title>
    <link href="http://xfeng.me/switch-to-hexo/"/>
    <id>http://xfeng.me/switch-to-hexo/</id>
    <published>2014-08-06T05:40:57.000Z</published>
    <updated>2015-12-25T04:05:44.000Z</updated>
    <content type="html"><![CDATA[<p>由于买的vps快到期了，不是很想续费，一年多基本就没登录过vps，博客也基本荒废了</p>
<p>所以准备留一个15刀一年的buyvm来做shadowsock服务器就好</p>
<p>而博客现在很流行静态博客，可以托管在github上，主机也省了，于是我也把原来的wordpress转换到hexo，部署到github</p>
<p>中间也了解其他静态博客生成工具，对Ruby没太多好感，而且hexo生成页面速度很快，最后选择了hexo
  <br>
  <a id="more"></a>
  <br>hexo设计的很不错，全部模块化，虽然不怎么懂js，不过简单看了下基本都懂，自己改了下模板，加了个多说的最新评论widget，增加了多说评论和jiathis分享服务，还有Google analysis，基本就这样用吧</p>
<p>另外发现Google adsense里居然还有点钱，不知道什么时候的，于是又蛋疼的把adsense挂上了，啥时候能凑够100提个现</p>]]></content>
    <summary type="html">
    <![CDATA[<p>由于买的vps快到期了，不是很想续费，一年多基本就没登录过vps，博客也基本荒废了</p>
<p>所以准备留一个15刀一年的buyvm来做shadowsock服务器就好</p>
<p>而博客现在很流行静态博客，可以托管在github上，主机也省了，于是我也把原来的wordpress转换到hexo，部署到github</p>
<p>中间也了解其他静态博客生成工具，对Ruby没太多好感，而且hexo生成页面速度很快，最后选择了hexo
  <br>]]>
    
    </summary>
    
      <category term="github" scheme="http://xfeng.me/tags/github/"/>
    
      <category term="hexo" scheme="http://xfeng.me/tags/hexo/"/>
    
      <category term="wordpress" scheme="http://xfeng.me/tags/wordpress/"/>
    
      <category term="Jottings" scheme="http://xfeng.me/category/jottings/"/>
    
      <category term="Web" scheme="http://xfeng.me/category/jottings/web/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[大版本SVN库备份快速重建方法]]></title>
    <link href="http://xfeng.me/large-version-svn-repo-fast-rebuild-backup/"/>
    <id>http://xfeng.me/large-version-svn-repo-fast-rebuild-backup/</id>
    <published>2013-10-26T08:44:44.000Z</published>
    <updated>2015-12-25T04:05:44.000Z</updated>
    <content type="html"><![CDATA[<p>svn仓库一般都是会配置svnsync的实时备份仓库，备库会从主库一个版本一个版本拷贝，但是如果主库已经有几十万版本后，想通过简单的svnsync init一个新的备份仓库，然后从0版本开始sync，所需的时间无法估计</p>
<p>为了快速重建备份，可以使用下面的方法来处理</p>
<p>1. 首先将主库hotcopy一份
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line">svnadmin hotcopy reponame reponame-bak</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>2. 将热备的备份同步到备机
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line">rsync -avz reponame-bak username@bakserver:/svnroot-path</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>3. 在备机增加改备库的svn权限
  <br>
  <a id="more"></a>
  <br>4. 对备库设置同步属性
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td>
        <td class="code"><pre><span class="line"><span class="comment">#设置主库的uuid</span></span><br><span class="line">svn ps svn:sync-from-uuid 主库的uuid --revprop -r <span class="number">0</span> http://bakserver/repo/reponame</span><br><span class="line"><span class="comment">#设置主库的url</span></span><br><span class="line">svn ps svn:sync-from-url http://masterserver/repo/reponame  --revprop -r <span class="number">0</span> http://bakserver/repo/reponame</span><br><span class="line"><span class="comment">#设置热备的最新版</span></span><br><span class="line">lastver=`svnlook youngest reponame-bak`</span><br><span class="line">svn ps svn:sync-last-merged-rev  <span class="variable">$lastver</span> --revprop -r <span class="number">0</span> http://bakserver/repo/reponame</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>5. 同步hotcopy后新提交的版本
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line">svnsync sync http://bakserver/repo/reponame</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>]]></content>
    <summary type="html">
    <![CDATA[<p>svn仓库一般都是会配置svnsync的实时备份仓库，备库会从主库一个版本一个版本拷贝，但是如果主库已经有几十万版本后，想通过简单的svnsync init一个新的备份仓库，然后从0版本开始sync，所需的时间无法估计</p>
<p>为了快速重建备份，可以使用下面的方法来处理</p>
<p>1. 首先将主库hotcopy一份
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line">svnadmin hotcopy reponame reponame-bak</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>2. 将热备的备份同步到备机
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line">rsync -avz reponame-bak username@bakserver:/svnroot-path</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>3. 在备机增加改备库的svn权限
  <br>]]>
    
    </summary>
    
      <category term="backup" scheme="http://xfeng.me/tags/backup/"/>
    
      <category term="svn" scheme="http://xfeng.me/tags/svn/"/>
    
      <category term="Linux" scheme="http://xfeng.me/category/linux/"/>
    
      <category term="SVN" scheme="http://xfeng.me/category/linux/svn/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[Awk求最大值正解]]></title>
    <link href="http://xfeng.me/awk-get-max/"/>
    <id>http://xfeng.me/awk-get-max/</id>
    <published>2013-08-08T13:15:57.000Z</published>
    <updated>2015-12-25T04:05:44.000Z</updated>
    <content type="html"><![CDATA[<p>这是一个很简单的功能，今天有同事问AWK如何实现，为什么最后结果是按字符串排序获取到的最大值，同事还在网上搜了下，给出的答案是清一色的，这些人压根不负责，难道你都没自己执行下命令看看返回的结果是否正确吗？只知道复制粘贴</p>
<p>例如下面一段文本
  <br>
  <figure class="highlight cpp">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td>
        <td class="code"><pre><span class="line"><span class="number">858</span></span><br><span class="line"><span class="number">569</span></span><br><span class="line"><span class="number">1858</span></span><br><span class="line"><span class="number">1526</span></span><br><span class="line"><span class="number">256</span></span><br><span class="line"><span class="number">382</span></span><br><span class="line"><span class="number">112</span></span><br><span class="line"><span class="number">1145</span></span><br><span class="line"><span class="number">921</span></span><br><span class="line"><span class="number">556</span></span><br><span class="line"><span class="number">228</span></span><br><span class="line"><span class="number">215</span></span><br><span class="line"><span class="number">1356</span></span><br><span class="line"><span class="number">158</span></span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>大部分的网上文章都给出了清一色的答案，如下：
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line">cat data|awk <span class="string">'BEGIN &#123;max = 0&#125; &#123;if ($1&gt;max) max=$1&#125; END &#123;print "Max=", max&#125;'</span></span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>负责任的说，获取到的最大值一定是921，而不是1858，因为第一位是9最大，按字符串比较的，而且为啥还要cat后在管道给awk。。。。
  <br>
  <a id="more"></a>
  <br>为了正确获取到最大值，需要让awk按数字去比较，因此在比较时需要先将变量强制转换为整数型，这样获取到的最大值就是正确的
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line">awk <span class="string">'BEGIN &#123;max = 0&#125; &#123;if ($1+0 &gt; max+0) max=$1&#125; END &#123;print "Max=", max&#125;'</span> data</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>这里可以看到比较时对两个变量先加0，就是做数据类型的转换</p>
<p>真心鄙视国内的文章不验证，直观复制粘贴转载，好无节操</p>
<p>更新：
  <br>如果想输出排序最大值所在行内容，也可以用awk实现
  <br>示例文本如下，以第一列排序
  <br>
  <figure class="highlight cpp">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td>
        <td class="code"><pre><span class="line"><span class="number">858</span> haha</span><br><span class="line"><span class="number">569</span> xixi</span><br><span class="line"><span class="number">1858</span> hehe</span><br><span class="line"><span class="number">1526</span> hello</span><br><span class="line"><span class="number">256</span> world</span><br><span class="line"><span class="number">382</span> print</span><br><span class="line"><span class="number">112</span> top</span><br><span class="line"><span class="number">1145</span> css</span><br><span class="line"><span class="number">921</span> html</span><br><span class="line"><span class="number">556</span> perl</span><br><span class="line"><span class="number">228</span> python</span><br><span class="line"><span class="number">215</span> shell</span><br><span class="line"><span class="number">1356</span> awk</span><br><span class="line"><span class="number">158</span> linux</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>一个比较简单的方法就是在记录最大值的时候，同时记录一下当前行，后面输出这个变量即可
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line">awk <span class="string">'BEGIN &#123;max = 0&#125; &#123;if ($1+0 &gt; max+0) &#123;max=$1 ;content=$0&#125; &#125; END &#123;print content&#125;'</span> data</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>这样最后输出的值应该是1858 hehe</p>]]></content>
    <summary type="html">
    <![CDATA[<p>这是一个很简单的功能，今天有同事问AWK如何实现，为什么最后结果是按字符串排序获取到的最大值，同事还在网上搜了下，给出的答案是清一色的，这些人压根不负责，难道你都没自己执行下命令看看返回的结果是否正确吗？只知道复制粘贴</p>
<p>例如下面一段文本
  <br>
  <figure class="highlight cpp">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td>
        <td
        class="code"><pre><span class="line"><span class="number">858</span></span><br><span class="line"><span class="number">569</span></span><br><span class="line"><span class="number">1858</span></span><br><span class="line"><span class="number">1526</span></span><br><span class="line"><span class="number">256</span></span><br><span class="line"><span class="number">382</span></span><br><span class="line"><span class="number">112</span></span><br><span class="line"><span class="number">1145</span></span><br><span class="line"><span class="number">921</span></span><br><span class="line"><span class="number">556</span></span><br><span class="line"><span class="number">228</span></span><br><span class="line"><span class="number">215</span></span><br><span class="line"><span class="number">1356</span></span><br><span class="line"><span class="number">158</span></span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>大部分的网上文章都给出了清一色的答案，如下：
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line">cat data|awk <span class="string">'BEGIN &#123;max = 0&#125; &#123;if ($1&gt;max) max=$1&#125; END &#123;print "Max=", max&#125;'</span></span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>负责任的说，获取到的最大值一定是921，而不是1858，因为第一位是9最大，按字符串比较的，而且为啥还要cat后在管道给awk。。。。
  <br>]]>
    
    </summary>
    
      <category term="Linux" scheme="http://xfeng.me/tags/linux/"/>
    
      <category term="awk" scheme="http://xfeng.me/tags/awk/"/>
    
      <category term="Linux" scheme="http://xfeng.me/category/linux/"/>
    
      <category term="Shell" scheme="http://xfeng.me/category/linux/shell/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[多看书城邀请码——免费获取正版书]]></title>
    <link href="http://xfeng.me/duokan-free-ebook/"/>
    <id>http://xfeng.me/duokan-free-ebook/</id>
    <published>2013-06-23T13:29:46.000Z</published>
    <updated>2015-12-25T04:05:44.000Z</updated>
    <content type="html"><![CDATA[<p>从kindle touch到现在kindle paperwhite一直都在用多看，多看书城现在越来越好了，书越来越多，质量还是很不错的</p>
<p>多看在kindle、iOS、Android都能使用，并且阅读记录，书签，笔记全部都能同步，体验很好，如果你还没开始使用多看，墙裂推荐你注册使用</p>
<p>这里如果你使用我的邀请码注册，你将免费获得对应的书籍，当然我推荐你使用我肯定也有好处，就是你以后再多看购买的第一本书籍我也讲免费获得，可以说是等价交换</p>
<p>一天基本就被用完了。。。看邀请历史有个人是注册了好多马甲，用了也不留个言说下，好多事应该是不会限免的，早知道就不直接贴出来了，需要的留言再给，搞马甲的基本也不会自己去买书</p>
<p>现在改为吧把所有邀请码都贴出来，有些是曾经限免过的书，但是限免过就不会再限免了，喜欢也可以用这个邀请码</p>
<p>另外如果你使用了哪个邀请码，请你回复告诉我，我标注已使用</p>
<p><strong>拒绝马甲，请选择一个你最喜欢的书，不要把资源全部占了</strong></p>
<p>快看看有没有你想要的书籍呢
  <br>
  <a id="more"></a>
</p>
<table>
  <thead>
    <tr>
      <th>邀请码</th>
      <th>书名</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>7E9P571595CC</td>
      <td><a href="http://book.duokan.com/%E6%97%85%E9%80%94%E7%9A%84%E8%84%9A%E5%8D%B0/b/2037" target="_blank" rel="external">旅途的脚印</a></td>
    </tr>
    <tr>
      <td>2E4P983D006C</td>
      <td><a href="http://book.duokan.com/%E4%BA%BA%E8%84%89%E6%98%AF%E8%AE%BE%E8%AE%A1%E5%87%BA%E6%9D%A5%E7%9A%84/b/24942" target="_blank" rel="external">人脉是设计出来的</a></td>
    </tr>
    <tr>
      <td>712P052750CA</td>
      <td><a href="http://book.duokan.com/%E4%B8%AD%E5%9B%BD%E6%B8%B8%E8%AE%B0/b/28247" target="_blank" rel="external">中国游记</a></td>
    </tr>
    <tr>
      <td>970P4FA31DFF</td>
      <td><a href="http://book.duokan.com/%E5%86%8D%E9%97%AE%E4%BA%BA%E9%97%B4/b/11187" target="_blank" rel="external">再问人间</a></td>
    </tr>
    <tr>
      <td>8ACP16C50966</td>
      <td><a href="http://book.duokan.com/%E4%BD%95%E4%B8%8D%E8%BF%99%E4%B8%AA%E5%91%A8%E6%9C%AB%E6%9D%A5%E5%88%9B%E4%B8%9A%EF%BC%88%E5%A4%A7%E5%B8%88%E8%BD%BB%E6%9D%BE%E8%AF%BB001%EF%BC%89/b/19502" target="_blank" rel="external">何不这个周末来创业（大师轻松读001）</a></td>
    </tr>
    <tr>
      <td>22AP78BEAB9F</td>
      <td><a href="http://book.duokan.com/%E6%8E%A8%E7%90%86%C2%B7%E7%A6%8F%E5%B0%94%E6%91%A9%E6%96%AF%E4%B8%93%E5%8F%B7/b/24737" target="_blank" rel="external">推理·福尔摩斯专号</a></td>
    </tr>
    <tr>
      <td>C35PE36939FC</td>
      <td><a href="http://book.duokan.com/%E5%8A%A0%E9%87%8C%E5%8D%9A%E5%A3%AB%E5%81%A5%E5%BA%B7%E8%82%B2%E5%84%BF%E7%BB%8F/b/11577" target="_blank" rel="external">加里博士健康育儿经</a></td>
    </tr>
    <tr>
      <td>EF4PBACAE4A1</td>
      <td><a href="http://book.duokan.com/%E6%88%91%E7%9F%A5%E9%81%93%E4%BD%A0%E6%98%AF%E6%80%8E%E4%B9%88%E5%89%A9%E4%B8%8B%E7%9A%84/b/11697" target="_blank" rel="external">我知道你是怎么剩下的</a></td>
    </tr>
    <tr>
      <td>95DP17B7E004</td>
      <td><a href="http://book.duokan.com/%E6%88%91%E6%98%AF%E7%88%AC%E8%A1%8C%E8%80%85%E5%B0%8F%E6%B1%9F/b/24127" target="_blank" rel="external">我是爬行者小江</a></td>
    </tr>
    <tr>
      <td>853PFD3BA952</td>
      <td><a href="http://book.duokan.com/%E5%88%9B%E6%84%8F%E4%BA%94%E6%8A%8A%E5%88%80%EF%BC%88%E5%A4%A7%E5%B8%88%E8%BD%BB%E6%9D%BE%E8%AF%BB003%EF%BC%89/b/19512" target="_blank" rel="external">创意五把刀（大师轻松读003）</a></td>
    </tr>
    <tr>
      <td>B2BPE2EA9D3D</td>
      <td><a href="http://book.duokan.com/%E5%BE%AE%E6%97%B6%E9%97%B4%E7%AE%A1%E7%90%86%E6%9C%AF%EF%BC%88%E5%A4%A7%E5%B8%88%E8%BD%BB%E6%9D%BE%E8%AF%BB002%EF%BC%89/b/19507" target="_blank" rel="external">微时间管理术（大师轻松读002）</a></td>
    </tr>
    <tr>
      <td>0D7P6C52FC07</td>
      <td><a href="http://book.duokan.com/%E5%9B%9B%E5%AD%A3%E7%9A%84%E8%A7%92%E5%BA%A6/b/5177" target="_blank" rel="external">四季的角度</a></td>
    </tr>
    <tr>
      <td>17BPAACE1A44</td>
      <td><a href="http://book.duokan.com/%E9%BA%BB%E5%A9%86%E8%B1%86%E8%85%90%E4%BD%9C%E6%96%87%E8%AF%BE/b/12897" target="_blank" rel="external">麻婆豆腐作文课</a></td>
    </tr>
    <tr>
      <td>241PA180C3C1</td>
      <td><a href="http://book.duokan.com/%E5%90%AC%E9%BB%84%E4%BB%81%E5%AE%87%E8%AE%B2%E4%B8%AD%E5%9B%BD%E5%8E%86%E5%8F%B2/b/18172" target="_blank" rel="external">听黄仁宇讲中国历史</a></td>
    </tr>
    <tr>
      <td>33FP85835229</td>
      <td><a href="http://book.duokan.com/%E9%BE%99%E6%96%87%E8%BA%AB%E7%9A%84%E5%A5%B3%E5%AD%A9/b/23287" target="_blank" rel="external">龙文身的女孩</a></td>
    </tr>
    <tr>
      <td>3C8PB366D236</td>
      <td><a href="http://book.duokan.com/%E5%8F%B2%E8%AE%B0%EF%BC%9A%E6%98%AF%E6%98%AF%E9%9D%9E%E9%9D%9E%E5%8F%B2%E7%8E%89%E6%9F%B1/b/32977" target="_blank" rel="external">史记：是是非非史玉柱</a></td>
    </tr>
    <tr>
      <td>42CPCA495E9C</td>
      <td><a href="http://book.duokan.com/%E6%BB%9A%E5%BA%8A%E5%8D%95%E5%BF%83%E7%90%86%E5%AD%A6/b/33507" target="_blank" rel="external">滚床单心理学</a></td>
    </tr>
    <tr>
      <td>9D0P1395F17F</td>
      <td><a href="http://book.duokan.com/%E9%AD%94%E9%AC%BC%E9%80%BB%E8%BE%91%E5%AD%A6/b/32842" target="_blank" rel="external">魔鬼逻辑学</a></td>
    </tr>
    <tr>
      <td>7F7PBB413A76</td>
      <td><a href="http://book.duokan.com/%E5%AD%A9%E5%AD%90%E6%98%AF%E7%88%B6%E6%AF%8D%E6%9C%80%E5%A4%A7%E7%9A%84%E4%BA%8B%E4%B8%9A/b/32707" target="_blank" rel="external">孩子是父母最大的事业</a></td>
    </tr>
    <tr>
      <td>0DEP633B4151</td>
      <td><a href="http://book.duokan.com/%E5%B0%B1%E6%83%B3%E5%BC%80%E9%97%B4%E5%B0%8F%E5%B0%8F%E5%92%96%E5%95%A1%E9%A6%86/b/20937" target="_blank" rel="external">就想开间小小咖啡馆</a></td>
    </tr>
    <tr>
      <td>0F2P9AC19B72</td>
      <td><a href="http://book.duokan.com/%E8%AF%B7%E5%8F%AB%E6%88%91%E5%B0%8F%E7%BA%AF%E6%B4%81_1%EF%BC%9A%E6%98%A5%E5%85%89%E4%B9%8D%E6%B3%84/b/32682" target="_blank" rel="external">请叫我小纯洁 1：春光乍泄</a></td>
    </tr>
    <tr>
      <td>F8CP3A0091DA</td>
      <td><a href="http://book.duokan.com/%E6%89%BE%E4%B8%AA%E6%9C%89%E7%BC%BA%E7%82%B9%E7%9A%84%E4%BA%BA%E7%BB%93%E5%A9%9A/b/35232" target="_blank" rel="external">找个有缺点的人结婚</a></td>
    </tr>
    <tr>
      <td>24BP74B9A2FE</td>
      <td><a href="http://book.duokan.com/%E5%BC%82%E8%A1%8C%E8%AF%A1%E9%97%BB%E5%BD%95_1%EF%BC%9A%E5%8D%97%E7%96%86%E8%B0%9C%E8%9B%8A/b/29067" target="_blank" rel="external">异行诡闻录 1：南疆谜蛊</a></td>
    </tr>
    <tr>
      <td>0A3P4D926427</td>
      <td><a href="http://book.duokan.com/%E7%8E%AF%E7%90%83%E7%A7%91%E5%AD%A6%EF%BC%882013%E5%B9%B45%E6%9C%88%EF%BC%89/b/34587" target="_blank" rel="external">环球科学（2013年5月）</a></td>
    </tr>
    <tr>
      <td>6FBP1566C16A</td>
      <td><a href="http://book.duokan.com/%E6%BD%9C%E4%BC%8F%E5%9C%A8%E5%8A%9E%E5%85%AC%E5%AE%A4/b/34332" target="_blank" rel="external">潜伏在办公室</a></td>
    </tr>
    <tr>
      <td>B2BP1DB6BE2F</td>
      <td><a href="http://book.duokan.com/%E6%A8%AA%E7%A9%BA%E5%87%BA%E4%B8%9690%E5%90%8E/b/17882" target="_blank" rel="external">横空出世90后</a></td>
    </tr>
    <tr>
      <td>E4BP788AB537</td>
      <td><a href="http://book.duokan.com/%E5%8B%BE%E6%90%AD%E5%AE%9D%E5%85%B8%EF%BC%88%E6%96%B0%E7%89%88%EF%BC%89/b/24937" target="_blank" rel="external">勾搭宝典（新版）</a></td>
    </tr>
    <tr>
      <td>C16P7B542F0F</td>
      <td><a href="http://book.duokan.com/%E5%85%94%E5%AD%90%E4%BB%80%E4%B9%88%E9%83%BD%E7%9F%A5%E9%81%93/b/17832" target="_blank" rel="external">兔子什么都知道</a></td>
    </tr>
    <tr>
      <td>73FPF922F2B7</td>
      <td><a href="http://book.duokan.com/%E5%81%87%E5%A6%82%E7%BB%99%E6%88%91%E4%B8%89%E5%A4%A9%E5%85%89%E6%98%8E/b/9792" target="_blank" rel="external">假如给我三天光明</a></td>
    </tr>
    <tr>
      <td>E42P4E0943E8</td>
      <td><a href="http://book.duokan.com/%E5%AE%89%E5%BE%92%E7%94%9F%E7%AB%A5%E8%AF%9D%E6%95%85%E4%BA%8B%E9%9B%86/b/13057" target="_blank" rel="external">安徒生童话故事集</a></td>
    </tr>
    <tr>
      <td>553P3B8CEE78</td>
      <td><a href="http://book.duokan.com/%E6%A3%AE%E6%9E%97%E6%8A%A5%C2%B7%E5%A4%8F/b/16122" target="_blank" rel="external">森林报·夏</a></td>
    </tr>
    <tr>
      <td>C1EPD87F63CB</td>
      <td><a href="http://book.duokan.com/%E5%87%89%E7%88%B1/b/37106" target="_blank" rel="external">凉爱</a></td>
    </tr>
    <tr>
      <td>968P621A2CD1</td>
      <td><a href="http://book.duokan.com/%E4%B8%AD%E5%9B%BD%C2%B7%E9%87%8E%E9%95%BF%E5%9F%8E/b/36895" target="_blank" rel="external">中国·野长城</a></td>
    </tr>
    <tr>
      <td>AF4P74600AE6</td>
      <td><a href="http://book.duokan.com/%E7%9C%9F%E6%80%95%E4%BD%A0%E6%98%AF%E4%B8%AA%E4%B9%96%E5%AD%A9%E5%AD%90/b/36840" target="_blank" rel="external">真怕你是个乖孩子</a></td>
    </tr>
    <tr>
      <td>01CP0D3E9557</td>
      <td><a href="http://book.duokan.com/%E7%88%B1%E6%98%AF%E6%9C%89%E6%95%85%E4%BA%8B%E7%9A%84%E6%97%85%E8%A1%8C/b/36835" target="_blank" rel="external">爱是有故事的旅行</a></td>
    </tr>
    <tr>
      <td>08CP88E6E1BB</td>
      <td><a href="http://book.duokan.com/%E3%80%8A%E8%AF%BB%E8%80%85%E3%80%8B%EF%BC%9A%E4%BA%BA%E7%94%9F%E7%99%BE%E5%91%B3/b/35162" target="_blank" rel="external">《读者》：人生百味</a></td>
    </tr>
    <tr>
      <td>69AP43F73726</td>
      <td><a href="http://book.duokan.com/%E6%B5%B7%E6%98%8E%E5%A8%81%E4%BD%9C%E5%93%81%E7%B3%BB%E5%88%97%EF%BC%9A%E8%80%81%E4%BA%BA%E4%B8%8E%E6%B5%B7/b/35212" target="_blank" rel="external">海明威作品系列：老人与海</a></td>
    </tr>
    <tr>
      <td>6ACP1B377ED5</td>
      <td><a href="http://book.duokan.com/%E8%83%9C%E5%A5%B3%E7%9A%84%E4%BB%A3%E4%BB%B7/b/35737" target="_blank" rel="external">胜女的代价</a></td>
    </tr>
    <tr>
      <td>E51P09CC7CE6</td>
      <td><a href="http://book.duokan.com/%E7%A7%98%E5%AF%86%EF%BC%9A%E4%B8%96%E7%95%8C%E4%B8%8A%E6%9C%80%E7%A5%9E%E5%A5%87%E7%9A%8424%E5%A0%82%E6%88%90%E5%8A%9F%E8%AF%BE/b/35182" target="_blank" rel="external">秘密：世界上最神奇的24堂成功课</a></td>
    </tr>
    <tr>
      <td>E1FP10E75EEF</td>
      <td><a href="http://book.duokan.com/%E7%8E%B0%E4%BB%A3%E7%BB%8F%E7%90%86%E4%BA%BA%E4%B8%8D%E5%8F%AF%E4%B8%8D%E7%9F%A5%E7%9A%84%E6%B3%95%E5%BE%8B%E7%9F%A5%E8%AF%86/b/34622" target="_blank" rel="external">现代经理人不可不知的法律知识</a></td>
    </tr>
    <tr>
      <td>C6FP8A5AC390</td>
      <td><a href="http://book.duokan.com/%E8%99%9A%E5%AE%9E%E4%B9%8B%E9%97%B4/b/31487" target="_blank" rel="external">虚实之间</a></td>
    </tr>
    <tr>
      <td>F84PF1975097</td>
      <td><a href="http://book.duokan.com/%E8%B6%8A%E4%BA%8C%E8%B6%8A%E5%8D%95%E7%BA%AF/b/37711" target="_blank" rel="external">越二越单纯</a></td>
    </tr>
    <tr>
      <td>8A1PBD2D1888</td>
      <td><a href="http://book.duokan.com/%E5%9C%88%E9%92%B1/b/36740" target="_blank" rel="external">圈钱</a></td>
    </tr>
    <tr>
      <td>ECEP0C396607</td>
      <td><a href="http://book.duokan.com/%E5%9B%BE%E5%8D%97%E5%BF%97%EF%BC%88%E4%B8%8A%EF%BC%89/b/36595" target="_blank" rel="external">图南志（上）</a></td>
    </tr>
    <tr>
      <td>2A4PEC3821B6</td>
      <td><a href="http://book.duokan.com/%E9%9D%92%E5%B8%AE%E6%95%99%E7%88%B6%E6%9D%9C%E6%9C%88%E7%AC%99%E5%85%A8%E4%BC%A0/b/36681" target="_blank" rel="external">青帮教父杜月笙全传</a></td>
    </tr>
    <tr>
      <td>C4CP73B672F4</td>
      <td><a href="http://book.duokan.com/%E9%81%93%E5%BE%B7%E7%BB%8F%E5%BF%83%E9%87%8A%EF%BC%88%E4%B8%8A%EF%BC%89/b/36589" target="_blank" rel="external">道德经心释（上）</a></td>
    </tr>
    <tr>
      <td>C0CP3A42891E</td>
      <td><a href="http://book.duokan.com/%E7%AC%A8%E8%8A%B1/b/37111" target="_blank" rel="external">笨花</a></td>
    </tr>
    <tr>
      <td>84EP216975C9</td>
      <td><a href="http://book.duokan.com/%E7%B2%BE%E7%A5%9E%E8%87%AA%E6%B2%BB/b/36674" target="_blank" rel="external">精神自治</a></td>
    </tr>
    <tr>
      <td>D08PC60166E6</td>
      <td><a href="http://book.duokan.com/%E5%A4%A9%E4%B8%8B%E5%A4%A7%E9%81%93/b/36707" target="_blank" rel="external">天下大道</a></td>
    </tr>
    <tr>
      <td>A93PA05FB465</td>
      <td><a href="http://book.duokan.com/%E6%88%98%E7%95%A5%E4%BA%BA%E7%94%9F%E8%A7%84%E5%88%92/b/36669" target="_blank" rel="external">战略人生规划</a></td>
    </tr>
    <tr>
      <td>4E9PEA40D725</td>
      <td><a href="http://book.duokan.com/%E5%BF%86%E5%BE%80%E8%BF%B0%E6%80%80/b/17322" target="_blank" rel="external">忆往述怀</a></td>
    </tr>
  </tbody>
</table>
<p>基本都是我付费买的书，限免收的书没贴出来，不定期更新，感兴趣的朋友可以注册一个</p>
<p>注册地址<a href="http://book.duokan.com/reg" title="注册多看" target="_blank" rel="external">http://book.duokan.com/reg</a></p>
<p>已被使用的邀请码
  <br>
  <li><del datetime="2013-06-24T15:38:15+00:00">F25P3A86B02C <a href="http://book.duokan.com/%E9%BA%A6%E8%82%AF%E9%94%A1%E5%92%A8%E8%AF%A2%E6%96%B9%E6%B3%95/b/21587" title="麦肯锡咨询方法" target="_blank" rel="external">《麦肯锡咨询方法》</a></del></li>
  <br>
  <li><del datetime="2013-06-24T15:38:15+00:00">CD8PE8F675A3 <a href="http://book.duokan.com/%E8%A7%A3%E8%AF%BB%E4%B8%AD%E5%9B%BD%E7%BB%8F%E6%B5%8E/b/21577" title="解读中国经济" target="_blank" rel="external">《解读中国经济》</a></del></li>
  <br>
  <li><del datetime="2013-06-24T15:38:15+00:00">F98P6FCA1157 <a href="http://book.duokan.com/%E7%BB%93%E7%BD%91/b/571" title="结网" target="_blank" rel="external">《结网》</a></del></li>
  <br>
  <li><del datetime="2013-06-24T15:38:15+00:00">DF1PE1DD6199 <a href="http://book.duokan.com/%E4%B8%8D%E5%81%9A%E7%BB%8F%E6%B5%8E%E7%99%BD%E7%97%B4/b/4002" title="不做经济白痴" target="_blank" rel="external">《不做经济白痴》</a></del></li>
  <br>
  <li><del datetime="2013-06-24T15:38:15+00:00">735P3552131E <a href="http://book.duokan.com/%E4%BA%BA%E4%BA%BA%E9%83%BD%E6%9C%89%E5%A5%BD%E5%B7%A5%E4%BD%9C/b/576" title="人人都有好工作" target="_blank" rel="external">《人人都有好工作》</a></del></li>
  <br>
  <li><del datetime="2013-06-24T15:38:15+00:00">214PF05E5B2B <a href="http://book.duokan.com/%E6%B2%B8%E8%85%BE%E5%8D%81%E4%BA%94%E5%B9%B4/b/15162" title="沸腾十五年" target="_blank" rel="external">《沸腾十五年》</a></del></li>
  <br>
  <li><del datetime="2013-06-24T15:38:15+00:00">4F9P40B3EBF7 <a href="http://book.duokan.com/%E6%9E%81%E7%AE%80%E6%AC%A7%E6%B4%B2%E5%8F%B2/b/24947" title="极简欧洲史" target="_blank" rel="external">《极简欧洲史》</a></del></li>
  <br>
  <li><del datetime="2013-06-24T15:38:15+00:00">976P721C08CB <a href="http://book.duokan.com/%E9%87%8D%E5%8F%A3%E5%91%B3%E5%BF%83%E7%90%86%E5%AD%A6/b/1432" title="重口味心理学" target="_blank" rel="external">《重口味心理学》</a></del></li>
</p>]]></content>
    <summary type="html">
    <![CDATA[<p>从kindle touch到现在kindle paperwhite一直都在用多看，多看书城现在越来越好了，书越来越多，质量还是很不错的</p>
<p>多看在kindle、iOS、Android都能使用，并且阅读记录，书签，笔记全部都能同步，体验很好，如果你还没开始使用多看，墙裂推荐你注册使用</p>
<p>这里如果你使用我的邀请码注册，你将免费获得对应的书籍，当然我推荐你使用我肯定也有好处，就是你以后再多看购买的第一本书籍我也讲免费获得，可以说是等价交换</p>
<p>一天基本就被用完了。。。看邀请历史有个人是注册了好多马甲，用了也不留个言说下，好多事应该是不会限免的，早知道就不直接贴出来了，需要的留言再给，搞马甲的基本也不会自己去买书</p>
<p>现在改为吧把所有邀请码都贴出来，有些是曾经限免过的书，但是限免过就不会再限免了，喜欢也可以用这个邀请码</p>
<p>另外如果你使用了哪个邀请码，请你回复告诉我，我标注已使用</p>
<p><strong>拒绝马甲，请选择一个你最喜欢的书，不要把资源全部占了</strong></p>
<p>快看看有没有你想要的书籍呢
  <br>]]>
    
    </summary>
    
      <category term="kindle" scheme="http://xfeng.me/tags/kindle/"/>
    
      <category term="Jottings" scheme="http://xfeng.me/category/jottings/"/>
    
      <category term="Web" scheme="http://xfeng.me/category/jottings/web/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[NERV人类补完计划]]></title>
    <link href="http://xfeng.me/nerv-human-instrumentality-project/"/>
    <id>http://xfeng.me/nerv-human-instrumentality-project/</id>
    <published>2013-06-23T12:27:49.000Z</published>
    <updated>2015-12-25T04:05:44.000Z</updated>
    <content type="html"><![CDATA[<h2 id="u4EBA_u7C7B_u8865_u5B8C_u8BA1_u5212"><a href="#u4EBA_u7C7B_u8865_u5B8C_u8BA1_u5212" class="headerlink" title="人类补完计划"></a>人类补完计划</h2>
<p>人类补完计划——人类（无论是肉体还是心灵）都是由脆弱的物质构成的，所以也就非常容易受到伤害，而在人与人之间，心灵的世界是彼此隔绝的，要使人类向更高的领域进化，就必须使人的心灵摆脱躯体的束缚，重新回到人类的诞生之地“莉莉斯之卵”中。唯有如此，才能最终拆除人与人之间的心灵屏障，使不同的心灵世界能够相互补充，走向进化的终点——成为永生的“神”。</p>
<p>上面是我最喜欢看的EVA里提到的人类补完计划，在当前这个优胜劣汰的时代，也该制定一个我自己的补完计划。</p>
<h2 id="IT_u5C4C_u4E1D_u611F_u609F"><a href="#IT_u5C4C_u4E1D_u611F_u609F" class="headerlink" title="IT屌丝感悟"></a>IT屌丝感悟</h2>
<p>在自动化、智能化越来越高的年代，运维大多数岗位都不得不转型，当发布可以完全自动化，监控系统能够收集到完整的运行信息，基于这些信息，根据运维经验判断可以制作出运维决策模型，甚至更加牛叉的AI，对于运行出现问题时就可以自动下线有问题的机器，或者自动扩容，自动切库，自动。。。。。。总之就是曾经大量苦逼的人力完成的东西可以通过智能自动化的系统完成，而且更加快速。当你的工作将被系统全部代替时，而你没有当前系统无法替代你处理的能力时，那就是悲剧的开始啊。
  <br>
  <a id="more"></a>
  <br>记得刚转岗到SCM，开始我单纯的以为maven就是用来编译java代码的工具，以为它就是一个mvn clean install命令，可见我是多么的小白。在这一年工作里经过很多项目问题的解决，慢慢清楚了是如何通过pom来定义依赖、插件，在编译java时是如何查找依赖，如何下载依赖包，虽然通过解决问题学习到了很多东西，但是对于maven的了解还是处于皮毛阶段。当我知道maven可以用来做更多事情的时候，我开始惊讶，开始想对它深入学习。</p>
<p>扯开下话题，互联网有一个特性，唯快不破。年初买了《打造facebook》，在回家的飞机上把它读完了，其中脸书的内部工具文化很有感触，而配管在研发过程中提供了大量的服务或工具，其中很大的一个目的就是为了提高研发效率。接着拉回mvn，我觉得配管就应该走在开发前，为提高研发效率不断改进。而当前我对mvn的了解如此薄弱，更别说当一个开发跟你说“我要用mvn3”时你该有多尴尬，如果只会mvn install，压根不知道mvn在其中做了什么，你就更不可能知道mvn3相比mvn2带来了什么，为什么开发想用mvn3。我可不想出现有一天因为配管导致研发效率无法提升，当然这可能只是效率提升其中一个方面，不过应该有点危机意识。同样的道理开发想用Git来管理代码，而作为一个配管连Git都没用过，你有如何了解开发为啥想git，git带来什么特性，它如何吸引人。随着时间的推移，随着接触到越来越多的东西，越来越觉得自己的弱小，对知识和能力的匮乏。</p>
<p>上面全是废话，无聊的吐槽，总之自己工作也快3年了，各方面都是个菜鸟，既然决定居然走技术路线，那就定计划加强自己的能力吧。</p>
<h2 id="u5B66_u4E60_u8BA1_u5212"><a href="#u5B66_u4E60_u8BA1_u5212" class="headerlink" title="学习计划"></a>学习计划</h2>
<p>今年的目标也相对简单，只剩下半年的时间了。</p>
<h3 id="Maven"><a href="#Maven" class="headerlink" title="Maven"></a>Maven</h3>
<p>系统的学习Maven，从安装到配置，到优化，学以致用
  <br><strong>《Maven实战》</strong>，Juven Xu是中国大力推从Maven者，中文专门讲Maven的也比较少，之前大概看过此书，很薄，简单入门工具书
  <br><strong>《Maven权威指南》</strong>，Sonatype官方书籍，Github有中文源码，英文印刷版暂时就算了，以后有空了要练习英语了再对比看下英文版</p>
<h3 id="Ant"><a href="#Ant" class="headerlink" title="Ant"></a>Ant</h3>
<p>虽然现在已经很少有人用Ant来管理整个项目了，但作为一个配管Ant还是必须要了解学习下，明白Maven和Ant的差别，另外我厂现在配置还在用Ant，最后的打包也是通过Ant，所以Ant的了解是必须的
  <br><strong>《Ant权威指南》</strong>，不做过于深入的学习，大概翻阅了解，对于任务这块重点学习下</p>
<h3 id="Git"><a href="#Git" class="headerlink" title="Git"></a>Git</h3>
<p>今年需要重点学习的东西，已经体验到Git很多特性带来的快感，另外作为scm新人，对subversion的了解暂时赶不上别人，那就对新的东西抓紧时间下手，不要再落在别人后面
  <br><strong>《Pro Git》</strong>，Git官方使用手册，仅适合入门日常使用，已看完大部分，但作为配管这部书远远不够
  <br><strong>《Git权威指南》</strong>，深入讲解Git的书籍，每一个Git命令实际做了什么，想要深入学习Git的必备书籍</p>
<h3 id="Python"><a href="#Python" class="headerlink" title="Python"></a>Python</h3>
<p>当前Python和Nodejs都很火，不过最后还是决定选python，只是python的版本兼容真操蛋，时刻想起两个python程序员，因为知道女方用的是python3而分手。。。
  <br>Python的中文书籍比较多，评价也好坏参半，不过作为入门感觉都差不多，大概通读完后上手直接写，后期才需要好的书籍点化下
  <br><strong>《Python学习手册》</strong>，Oreilly的动物书，作为程序员要学新语言，不管看不看，动物书还是得搞一本的
  <br><strong>《Python核心编程》</strong>，很多人在看，但是译者也很没节操，不过我只是个学习者，不纠结那么多
  <br>最后得说一句，以后除了修改原来的脚本会用Perl，否则必须得用Python，不然就剁手
  <br>最近最后几个Perl脚本用面向对象的方法写的，真的很坑爹，本来准备继续写子类，但是perl只会继承方法，得自己搞定属性值继承，果断放弃，不想继续被Perl折腾，所以改Python了</p>
<h3 id="u9762_u5411_u5BF9_u8C61"><a href="#u9762_u5411_u5BF9_u8C61" class="headerlink" title="面向对象"></a>面向对象</h3>
<p>毕业后由于没做开发，大量的脚本编写都是面向过程的，以至于最近想写OO都还找书籍重新复习了下面向对象的概念，也重新体验到OO的快感，所以要重新好好学习下OO
  <br><strong>《冒号课堂》</strong>，一本比较老的讲解面向对象编程思想的书，评价很高</p>
<h3 id="u914D_u7BA1_u7406_u8BBA"><a href="#u914D_u7BA1_u7406_u8BBA" class="headerlink" title="配管理论"></a>配管理论</h3>
<p>我就是那种半路出家的和尚，配管的基本理念简单看过，但专业的书籍从来没去看过，还是有必要深入学习下
  <br><strong>《未雨绸缪》</strong>，国内专门讲解配管知识的书不是很多，这本书评价还不错</p>
<p>这里列出了9本书，今年一定要读完，Google Calendar重新用起来，定制计划每天提醒，争取明年在自己的专业范畴内不做小白。</p>
<p>最后我要吐槽下，啥都有权威指南，为啥Subversion没有呢，找到的几本书都太面向基本操作，看来想更深入了解Subversion还是只能慢慢看Release Notes和和官方文档吧</p>]]></content>
    <summary type="html">
    <![CDATA[<h2 id="u4EBA_u7C7B_u8865_u5B8C_u8BA1_u5212"><a href="#u4EBA_u7C7B_u8865_u5B8C_u8BA1_u5212" class="headerlink" title="人类补完计划"></a>人类补完计划</h2>
<p>人类补完计划——人类（无论是肉体还是心灵）都是由脆弱的物质构成的，所以也就非常容易受到伤害，而在人与人之间，心灵的世界是彼此隔绝的，要使人类向更高的领域进化，就必须使人的心灵摆脱躯体的束缚，重新回到人类的诞生之地“莉莉斯之卵”中。唯有如此，才能最终拆除人与人之间的心灵屏障，使不同的心灵世界能够相互补充，走向进化的终点——成为永生的“神”。</p>
<p>上面是我最喜欢看的EVA里提到的人类补完计划，在当前这个优胜劣汰的时代，也该制定一个我自己的补完计划。</p>
<h2 id="IT_u5C4C_u4E1D_u611F_u609F"><a href="#IT_u5C4C_u4E1D_u611F_u609F" class="headerlink" title="IT屌丝感悟"></a>IT屌丝感悟</h2>
<p>在自动化、智能化越来越高的年代，运维大多数岗位都不得不转型，当发布可以完全自动化，监控系统能够收集到完整的运行信息，基于这些信息，根据运维经验判断可以制作出运维决策模型，甚至更加牛叉的AI，对于运行出现问题时就可以自动下线有问题的机器，或者自动扩容，自动切库，自动。。。。。。总之就是曾经大量苦逼的人力完成的东西可以通过智能自动化的系统完成，而且更加快速。当你的工作将被系统全部代替时，而你没有当前系统无法替代你处理的能力时，那就是悲剧的开始啊。
  <br>]]>
    
    </summary>
    
      <category term="Python" scheme="http://xfeng.me/tags/python/"/>
    
      <category term="ant" scheme="http://xfeng.me/tags/ant/"/>
    
      <category term="git" scheme="http://xfeng.me/tags/git/"/>
    
      <category term="maven" scheme="http://xfeng.me/tags/maven/"/>
    
      <category term="mvn" scheme="http://xfeng.me/tags/mvn/"/>
    
      <category term="perl" scheme="http://xfeng.me/tags/perl/"/>
    
      <category term="scm" scheme="http://xfeng.me/tags/scm/"/>
    
      <category term="svn" scheme="http://xfeng.me/tags/svn/"/>
    
      <category term="Jottings" scheme="http://xfeng.me/category/jottings/"/>
    
      <category term="Life" scheme="http://xfeng.me/category/jottings/life/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[提交异常文件名导致SVN库无法操作的解决方案]]></title>
    <link href="http://xfeng.me/submit-abnormal-file-causes-svn-error-solution/"/>
    <id>http://xfeng.me/submit-abnormal-file-causes-svn-error-solution/</id>
    <published>2012-12-29T04:49:24.000Z</published>
    <updated>2015-12-25T04:05:44.000Z</updated>
    <content type="html"><![CDATA[<p>昨天本来应该是挺happy的一天，元旦假期即将开始了，但是由于一个开发同学向SVN库中提交了一个文件名包含特殊字符的文件，导致无法更新，检出，也无法增量同步到备库，所有操作只要碰到那个文件则会被强制中断，日志也无法查看了</p>
<p>最后无奈的只能选择将整个库dump出来，然后使用svndumpfilter来抽取那个有问题的文件，然后将处理后的dump文件重新load到一个新的SVN仓库，具体的方法如下。</p>
<p>首先先找到那个有问题的版本，通过看svn日志，发现整个仓库最新版是2696，而日志只能显示2696和2695两个版本，而2694开始就显示不了日志
  <br><img src="http://img.xfeng.me/yupoo/CwE1oKhx.jpg!medium" alt="svn log">
  <a id="more"></a>
  <br>如果选择查看2693以前的版本则一切正常，因此确定有问题的那个文件是2694这个版本提交的
  <br><img src="http://img.xfeng.me/yupoo/CwE1nJdZ.jpg!medium" alt="svn log"></p>
<p>dump出0到2693的记录，然后dump出2694到head的记录，然后充2694到head的dump文件中抽取那个有问题的文件
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td>
        <td class="code"><pre><span class="line">svnadmin dump -r <span class="number">0</span>:<span class="number">2693</span> --incremental svnrepo &gt; svnrepo.<span class="number">0.2693</span>.dump</span><br><span class="line">svnadmin dump -r <span class="number">2694</span>:HEAD --incremental svnrepo &gt; svnrepo.<span class="number">2694</span>.head.dump</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>然后新建一个svn仓库，将0到2693的记录导入
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td>
        <td class="code"><pre><span class="line">svnadmin create svnrepo2</span><br><span class="line">svnadmin load svnrepo2 &lt; svnrepo.<span class="number">0.2693</span>.dump</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>然后从2694中抽取有问题那个文件，但是由于是文件名中有特殊字符，因此没法直接指定到那个文件，只能指定到该文件所在目录，因此可能会多抽取该文件所在目录的提交的其他文件，暂时没有别的办法，只能解决完后重新提交一次</p>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br></pre></td>
      <td class="code"><pre><span class="line">svndumpfilter exclude <span class="string">"branches/xxxxxx/xxx/xxx"</span> &lt; svnrepo.<span class="number">2694</span>.head.dump &gt; svnrepo.<span class="number">2694</span>.head.dump.exclude</span><br></pre></td>
    </tr>
  </table>
</figure>
<p>执行该命令后，会提示被丢弃的文件有哪些，确定有问题的那个文件被丢弃后，再记录下多丢弃的文件，后面需要重新提交</p>
<p>将处理后的dump文件导入到新的仓库
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br></pre></td>
        <td class="code"><pre><span class="line">svnadmin load svnrepo2 &lt; svnrepo.<span class="number">2694</span>.head.dump.exclude</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>完成后，检查仓库版本差异，可以看到2964的提交记录，少了之前丢弃的那几个文件
  <br><img src="http://img.xfeng.me/yupoo/CwE1pwMg.jpg!medium" alt="svn log">
  <br>确认没问题后，将新库的uuid设置为老库的uuid，重新提交者几个文件即可</p>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td>
      <td class="code"><pre><span class="line">svn info http://svnrul/svnrepo</span><br><span class="line">URL: http://svnrul/svnrepo</span><br><span class="line">版本库根: http://svnrul/svnrepo</span><br><span class="line">版本库 UUID: xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx</span><br><span class="line"></span><br><span class="line">svnadmin setuuid svnrepo2 xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx</span><br></pre></td>
    </tr>
  </table>
</figure>
<p>这个办法同样适用于想从SVN仓库中彻底删除一个文件</p>]]></content>
    <summary type="html">
    <![CDATA[<p>昨天本来应该是挺happy的一天，元旦假期即将开始了，但是由于一个开发同学向SVN库中提交了一个文件名包含特殊字符的文件，导致无法更新，检出，也无法增量同步到备库，所有操作只要碰到那个文件则会被强制中断，日志也无法查看了</p>
<p>最后无奈的只能选择将整个库dump出来，然后使用svndumpfilter来抽取那个有问题的文件，然后将处理后的dump文件重新load到一个新的SVN仓库，具体的方法如下。</p>
<p>首先先找到那个有问题的版本，通过看svn日志，发现整个仓库最新版是2696，而日志只能显示2696和2695两个版本，而2694开始就显示不了日志
  <br><img src="http://img.xfeng.me/yupoo/CwE1oKhx.jpg!medium" alt="svn log">]]>
    
    </summary>
    
      <category term="dump" scheme="http://xfeng.me/tags/dump/"/>
    
      <category term="svn" scheme="http://xfeng.me/tags/svn/"/>
    
      <category term="Linux" scheme="http://xfeng.me/category/linux/"/>
    
      <category term="SVN" scheme="http://xfeng.me/category/linux/svn/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[SVN负载均衡方案]]></title>
    <link href="http://xfeng.me/svn-load-balance-solutions/"/>
    <id>http://xfeng.me/svn-load-balance-solutions/</id>
    <published>2012-09-16T08:54:57.000Z</published>
    <updated>2015-12-25T04:05:44.000Z</updated>
    <content type="html"><![CDATA[<p>由于svn是集中式管理的，所有的读取写入都需要集中到一台服务器，但是当使用人数相当庞大时，一台服务器很难支撑，因此就需要想办法实现SVN服务器集群的负载均衡。</p>
<p>国外有一家公司专门提供SVN负载均衡的解决方案，由于是商业解决方案，因此从网站上看不到任何解决次问题的技术文档，而国内压根搜不到这类文章，但是很多公司一定在使用集群式的SVN，例如Google的Code，如此庞大的请求量，如果每个repo都仅靠一台服务器很难支撑，但是也办法知道Google是如何解决的。</p>
<p>我自己瞎折腾出一个方案，不过只能说是雏形，其中可能还会涉及auth缓存以及auth信息如何在多集群间传递而不中断用户操作，各位看官路过如果有建议或者发现问题非常欢迎指出。</p>
<p>方案很简单，由于svn大部分都是update或者checkout请求，而commit这种写操作相当非常少，思想就是读写分离，提高svn的性能想到一个方法就是类似DB的读写分离。因为svn这种集中式管理的仓库，写还是必须写到同一地方，但是读取仓库内容可以分散到多个备库，减轻主库压力，而且大部分请求都是读取，写入请求相当很少。
  <br>
  <a id="more"></a>
  <br>而读写分离的方法也很直接，通过Nginx或HAProxy在前端根据请求方法进行转发，把写请求转发到SVN Master，同时实时同步到SVN Slave，而读请求转发到SVN Slave集群。读写分离后，从所有请求都一台SVN服务器处理变为由多台SVN服务器同时提供服务，由此解决大量用户更新代码或检出代码使SVN服务器负载彪高，检出代码缓慢的情况。</p>
<p>当commit新版本后，svnmaster同步到svn slave，由于需要同步多台备库，在主库提交完后，需要等待post-commit钩子执行完毕后返回才能算提交完成，如果同步备库很多以后，直接在post-commit钩子中执行svnsync的方法会导致用户提交代码等待时间过长。这里可以采用钩子中像本地的一个daemo程序发送一个请求后直接返回，后daemo程序去执行同步。</p>
<p>大概的架构图如下：
  <br><img src="http://img.xfeng.me/yupoo/CgQJhl9g.jpg!medium" alt="svn负载均衡">
  <br>通过网络LB设备将请求分发到两台Nginx，如果一台Nginx crash，由LB设备健康检查到后自动踢出，然后通过Nginx根据请求方法进行转发，Nginx的upstream也可进行健康检查，如果一台备库crash也可自动踢出。</p>
<p>还需要写脚本检查备库与主库直接的同步状态，如果失败并多次重新同步失败，需要踢出备库集群，这个可直接修改nginx配置中upstream后reload即可。</p>
<p>废话了一大篇，下面讲解一些实际配置：</p>
<p>首先为了保证用户从多个备库读取数据能正常，备库启动后，必须使用svnadmin setuuid将备库和主库的uuid设为同一个</p>
<p>简单的Nginx配置如下：
  <br>
  <figure class="highlight">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td>
        <td class="code"><pre><span class="line">http</span><br><span class="line">&#123;</span><br><span class="line">                upstream svnmaster</span><br><span class="line">                &#123;</span><br><span class="line">                        server master.svn.net:80;</span><br><span class="line">                &#125;</span><br><span class="line">                upstream svnslave</span><br><span class="line">                &#123;</span><br><span class="line">                        server salve1.svn.net:80;</span><br><span class="line">                        server salve2.svn.net:80;</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                log_format  svn_log  '$remote_addr - $remote_user [$time_local] "$request" '</span><br><span class="line">             '$status $body_bytes_sent "forward:$upstream_addr" "$upstream_status" "$upstream_response_time" '</span><br><span class="line">             '"$http_user_agent" ';</span><br><span class="line"></span><br><span class="line">server</span><br><span class="line">        &#123;</span><br><span class="line">                listen       80;</span><br><span class="line">                server_name svn.net;</span><br><span class="line"></span><br><span class="line">               location ~ /svn</span><br><span class="line">               &#123;</span><br><span class="line">                        proxy_set_header Host $host;</span><br><span class="line">                        proxy_set_header X-Real-IP $remote_addr;</span><br><span class="line">                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span><br><span class="line"></span><br><span class="line">                        if ( $request_method ~* "^(MOVE|COPY|DELETE|LOCK|UNLOCK|MERGE|PUT|POST|PROPPATCH|MKCOL)$" )</span><br><span class="line">                        &#123;</span><br><span class="line">                               proxy_pass      http://svnmaster;</span><br><span class="line">                        &#125;</span><br><span class="line">                        if ( $request_method ~* "^(OPTIONS|PROPFIND|GET|REPORT|MKACTIVITY|CHECKOUT)$" )</span><br><span class="line">                        &#123;</span><br><span class="line">                               proxy_pass      http://svnslave;</span><br><span class="line">                        &#125;</span><br><span class="line"></span><br><span class="line">                       access_log  /home/log/svn.log  svn_log;</span><br><span class="line">               &#125;</span><br><span class="line">        &#125;</span><br><span class="line">&#125;</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>这个方法简单测试提交、检出，删除，复制都是没问题的，但是还是测试过在高并发提交下会出现什么问题，如果有需求的朋友可以尝试下，如果有需要改善的地方非常欢迎指出。</p>
<p>P.S. 国外提供商业解决方案的网站，有兴趣的同学可以看一下 <a href="http://www.wandisco.com/subversion/clustering" title="Subversion Clustering" target="_blank" rel="external">http://www.wandisco.com/subversion/clustering</a></p>]]></content>
    <summary type="html">
    <![CDATA[<p>由于svn是集中式管理的，所有的读取写入都需要集中到一台服务器，但是当使用人数相当庞大时，一台服务器很难支撑，因此就需要想办法实现SVN服务器集群的负载均衡。</p>
<p>国外有一家公司专门提供SVN负载均衡的解决方案，由于是商业解决方案，因此从网站上看不到任何解决次问题的技术文档，而国内压根搜不到这类文章，但是很多公司一定在使用集群式的SVN，例如Google的Code，如此庞大的请求量，如果每个repo都仅靠一台服务器很难支撑，但是也办法知道Google是如何解决的。</p>
<p>我自己瞎折腾出一个方案，不过只能说是雏形，其中可能还会涉及auth缓存以及auth信息如何在多集群间传递而不中断用户操作，各位看官路过如果有建议或者发现问题非常欢迎指出。</p>
<p>方案很简单，由于svn大部分都是update或者checkout请求，而commit这种写操作相当非常少，思想就是读写分离，提高svn的性能想到一个方法就是类似DB的读写分离。因为svn这种集中式管理的仓库，写还是必须写到同一地方，但是读取仓库内容可以分散到多个备库，减轻主库压力，而且大部分请求都是读取，写入请求相当很少。
  <br>]]>
    
    </summary>
    
      <category term="Linux" scheme="http://xfeng.me/tags/linux/"/>
    
      <category term="nginx" scheme="http://xfeng.me/tags/nginx/"/>
    
      <category term="svn" scheme="http://xfeng.me/tags/svn/"/>
    
      <category term="Linux" scheme="http://xfeng.me/category/linux/"/>
    
      <category term="SVN" scheme="http://xfeng.me/category/linux/svn/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[CentOS安装L2TP VPN笔记]]></title>
    <link href="http://xfeng.me/centos-install-l2tp-vpn-note/"/>
    <id>http://xfeng.me/centos-install-l2tp-vpn-note/</id>
    <published>2012-07-29T08:49:40.000Z</published>
    <updated>2015-12-25T04:05:44.000Z</updated>
    <content type="html"><![CDATA[<p>换了个新vps，之前一直用pptp和openvpn，这次准备尝试下l2tp，记录下安装过程</p>
<p>ip里也就能通过NCSetting快速启动vpn了，openvpn没有在NCSetting里的设置
  <br><img src="http://img.xfeng.me/yupoo/C9oEw4OC.jpg!medium" alt="L2TP VPN">
  <br>首先需要卸载已安装的openswan，我因为yum install安装的openswan版本有bug，导致我折腾一天也没连接成功，所以建议直接下载指定版本的源码编译安装</p>
<h3 id="u5B89_u88C5ipsec"><a href="#u5B89_u88C5ipsec" class="headerlink" title="安装ipsec"></a>安装ipsec</h3>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td>
      <td class="code"><pre><span class="line">yum remove -y openswan</span><br><span class="line">wget http://www.openswan.org/download/openswan-<span class="number">2.6</span>.<span class="number">24</span>.tar.gz</span><br><span class="line">tar zxvf openswan-<span class="number">2.6</span>.<span class="number">24</span>.tar.gz</span><br><span class="line"><span class="built_in">cd</span> openswan-<span class="number">2.6</span>.<span class="number">24</span></span><br><span class="line">make programs install</span><br></pre></td>
    </tr>
  </table>
</figure>
<a id="more"></a>
<h3 id="u5B89_u88C5_u5FC5_u987B_u7684_u6A21_u5757"><a href="#u5B89_u88C5_u5FC5_u987B_u7684_u6A21_u5757" class="headerlink" title="安装必须的模块"></a>安装必须的模块</h3>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br></pre></td>
      <td class="code"><pre><span class="line">yum install ppp iptables libpcap-devel</span><br></pre></td>
    </tr>
  </table>
</figure>
<h3 id="u914D_u7F6Eipsec"><a href="#u914D_u7F6Eipsec" class="headerlink" title="配置ipsec"></a>配置ipsec</h3>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td>
      <td class="code"><pre><span class="line">rm -rf /etc/ipsec.conf</span><br><span class="line">touch /etc/ipsec.conf</span><br><span class="line">cat &gt;&gt;/etc/ipsec.conf&lt; &lt;EOF</span><br><span class="line">config setup</span><br><span class="line">    nat_traversal=yes</span><br><span class="line">    virtual_private=%v4:<span class="number">10.0</span>.<span class="number">0.0</span>/<span class="number">8</span>,%v4:<span class="number">192.168</span>.<span class="number">0.0</span>/<span class="number">16</span>,%v4:<span class="number">172.16</span>.<span class="number">0.0</span>/<span class="number">12</span></span><br><span class="line">    oe=off</span><br><span class="line">    protostack=netkey</span><br><span class="line"></span><br><span class="line">conn L2TP-PSK-NAT</span><br><span class="line">    rightsubnet=vhost:%priv</span><br><span class="line">    also=L2TP-PSK-noNAT</span><br><span class="line"></span><br><span class="line">conn L2TP-PSK-noNAT</span><br><span class="line">    authby=secret</span><br><span class="line">    pfs=no</span><br><span class="line">    auto=add</span><br><span class="line">    keyingtries=<span class="number">3</span></span><br><span class="line">    rekey=no</span><br><span class="line">    ikelifetime=<span class="number">8</span>h</span><br><span class="line">    keylife=<span class="number">1</span>h</span><br><span class="line">    <span class="built_in">type</span>=transport</span><br><span class="line">    left=<span class="variable">$ip</span>  <span class="comment">#替换成vps的ip</span></span><br><span class="line">    leftprotoport=<span class="number">17</span>/<span class="number">1701</span></span><br><span class="line">    right=%any</span><br><span class="line">    rightprotoport=<span class="number">17</span>/%any</span><br><span class="line">EOF</span><br></pre></td>
    </tr>
  </table>
</figure>
<h3 id="u914D_u7F6E_u5BC6_u94A5"><a href="#u914D_u7F6E_u5BC6_u94A5" class="headerlink" title="配置密钥"></a>配置密钥</h3>
<p>替换vipip和key</p>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br></pre></td>
      <td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="string">"<span class="variable">$your_vps_ip</span> %any: PSK \"<span class="variable">$your_key</span>\""</span> &gt;/etc/ipsec.d/l2tp.secrets</span><br></pre></td>
    </tr>
  </table>
</figure>
<h3 id="u914D_u7F6E_u8F6C_u53D1"><a href="#u914D_u7F6E_u8F6C_u53D1" class="headerlink" title="配置转发"></a>配置转发</h3>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td>
      <td class="code"><pre><span class="line">sed -i <span class="string">'s/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/g'</span> /etc/sysctl.conf</span><br><span class="line">sysctl -p</span><br><span class="line"><span class="keyword">for</span> each <span class="keyword">in</span> /proc/sys/net/ipv4/conf/*                                                                                                      </span><br><span class="line"><span class="keyword">do</span>                                                                                                                                         </span><br><span class="line"><span class="built_in">echo</span> <span class="number">0</span> &gt; <span class="variable">$each</span>/accept_redirects                                                                                                            </span><br><span class="line"><span class="built_in">echo</span> <span class="number">0</span> &gt; <span class="variable">$each</span>/send_redirects                                                                                                              </span><br><span class="line"><span class="keyword">done</span> </span><br><span class="line">iptables -t nat -A POSTROUTING -j MASQUERADE</span><br></pre></td>
    </tr>
  </table>
</figure>
<h3 id="u9A8C_u8BC1ipsec_u914D_u7F6E"><a href="#u9A8C_u8BC1ipsec_u914D_u7F6E" class="headerlink" title="验证ipsec配置"></a>验证ipsec配置</h3>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td>
      <td class="code"><pre><span class="line">/etc/init.d/ipsec restart                                                                                                                  </span><br><span class="line">ipsec verify </span><br><span class="line">Checking your system to see <span class="keyword">if</span> IPsec got installed and started correctly:</span><br><span class="line">Version check and ipsec on-path                                 [OK]</span><br><span class="line">Linux Openswan U2.<span class="number">6.24</span>/K2.<span class="number">6.32</span>-<span class="number">71.29</span>.<span class="number">1</span>.el6.i686 (netkey)</span><br><span class="line">Checking <span class="keyword">for</span> IPsec support <span class="keyword">in</span> kernel                            [OK]</span><br><span class="line">NETKEY detected, testing <span class="keyword">for</span> disabled ICMP send_redirects       [OK]</span><br><span class="line">NETKEY detected, testing <span class="keyword">for</span> disabled ICMP accept_redirects     [OK]</span><br><span class="line">Checking <span class="keyword">for</span> RSA private key (/etc/ipsec.secrets)               [OK]</span><br><span class="line">Checking that pluto is running                                  [OK]</span><br><span class="line">Pluto listening <span class="keyword">for</span> IKE on udp <span class="number">500</span>                              [OK]</span><br><span class="line">Pluto listening <span class="keyword">for</span> NAT-T on udp <span class="number">4500</span>                           [OK]</span><br><span class="line">Two or more interfaces found, checking IP forwarding            [OK]</span><br><span class="line">Checking NAT and MASQUERADEing                                  [N/A]</span><br><span class="line">Checking <span class="keyword">for</span> <span class="string">'ip'</span> <span class="built_in">command</span>                                       [OK]</span><br><span class="line">Checking <span class="keyword">for</span> <span class="string">'iptables'</span> <span class="built_in">command</span>                                 [OK]</span><br><span class="line">Opportunistic Encryption Support                                [DISABLED]</span><br></pre></td>
    </tr>
  </table>
</figure>
<h3 id="u5B89_u88C5x2ltpd"><a href="#u5B89_u88C5x2ltpd" class="headerlink" title="安装x2ltpd"></a>安装x2ltpd</h3>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td>
      <td class="code"><pre><span class="line">wget http://www.xelerance.com/wp-content/uploads/software/xl2tpd/xl2tpd-<span class="number">1.3</span>.<span class="number">0</span>.tar.gz</span><br><span class="line">tar xvf xl2tpd-<span class="number">1.3</span>.<span class="number">0</span>.tar.gz</span><br><span class="line">make install</span><br><span class="line">mkdir /var/run/xl2tpd</span><br><span class="line">ln <span class="operator">-s</span> /usr/<span class="built_in">local</span>/sbin/l2tp-control /var/run/xl2tpd/l2tp-control</span><br><span class="line">mkdir /etc/xl2tpd</span><br></pre></td>
    </tr>
  </table>
</figure>
<h3 id="u914D_u7F6Exl2tpd"><a href="#u914D_u7F6Exl2tpd" class="headerlink" title="配置xl2tpd"></a>配置xl2tpd</h3>
<p>修改/etc/xl2tpd/xl2tpd.conf
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td>
        <td class="code"><pre><span class="line">[global]</span><br><span class="line">listen-addr = <span class="variable">$your_vps_ip</span> <span class="comment">#替换成你的vpsip</span></span><br><span class="line">ipsec saref = yes</span><br><span class="line">[lns default]</span><br><span class="line">ip range = <span class="number">192.168</span>.<span class="number">30.10</span>-<span class="number">192.168</span>.<span class="number">30.20</span></span><br><span class="line"><span class="built_in">local</span> ip = <span class="number">192.168</span>.<span class="number">30.1</span></span><br><span class="line">require chap = yes</span><br><span class="line">refuse pap = yes</span><br><span class="line">require authentication = yes</span><br><span class="line">ppp debug = yes</span><br><span class="line">pppoptfile = /etc/ppp/options.xl2tpd</span><br><span class="line">length bit = yes</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>编辑 /etc/ppp/options.xl2tpd
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td>
        <td class="code"><pre><span class="line">require-mschap-v2</span><br><span class="line">ipcp-accept-local</span><br><span class="line">ipcp-accept-remote</span><br><span class="line">ms-dns  <span class="number">8.8</span>.<span class="number">8.8</span></span><br><span class="line">ms-dns  <span class="number">8.8</span>.<span class="number">4.4</span></span><br><span class="line">asyncmap <span class="number">0</span></span><br><span class="line">noccp</span><br><span class="line">auth</span><br><span class="line">crtscts</span><br><span class="line">hide-password</span><br><span class="line">debug</span><br><span class="line">modem</span><br><span class="line">lock</span><br><span class="line">proxyarp</span><br><span class="line">name l2tpd</span><br><span class="line">lcp-echo-interval <span class="number">30</span></span><br><span class="line">lcp-echo-failure <span class="number">4</span></span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>配置用户和密码 /etc/ppp/chap-secrets
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td>
        <td class="code"><pre><span class="line"><span class="comment"># Secrets for authentication using CHAP</span></span><br><span class="line"><span class="comment"># client        server  secret                  IP addresses</span></span><br><span class="line">name         l2tpd   password                *</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<h3 id="u914D_u7F6E_u8F6C_u53D1_u89C4_u5219"><a href="#u914D_u7F6E_u8F6C_u53D1_u89C4_u5219" class="headerlink" title="配置转发规则"></a>配置转发规则</h3>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td>
      <td class="code"><pre><span class="line">iptables -t nat -A POSTROUTING <span class="operator">-s</span> <span class="number">192.168</span>.<span class="number">30.0</span>/<span class="number">24</span> -o eth0 -j MASQUERADE </span><br><span class="line">iptables -t nat -A POSTROUTING <span class="operator">-s</span> <span class="number">192.168</span>.<span class="number">30.0</span>/<span class="number">24</span> -j SNAT --to-source <span class="variable">$your_vps_ip</span></span><br></pre></td>
    </tr>
  </table>
</figure>
<h3 id="u542F_u52A8xl2tp"><a href="#u542F_u52A8xl2tp" class="headerlink" title="启动xl2tp"></a>启动xl2tp</h3>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br></pre></td>
      <td class="code"><pre><span class="line">xl2tpd -D &amp;</span><br></pre></td>
    </tr>
  </table>
</figure>
<p>现在应该已经正常运行了，可以在你的手机或者电脑上新建一个l2tp连接测试</p>
<h3 id="u81EA_u542F_u52A8_u914D_u7F6E"><a href="#u81EA_u542F_u52A8_u914D_u7F6E" class="headerlink" title="自启动配置"></a>自启动配置</h3>
<p>为了保证每次vps重启后都正常启动l2tp服务，我们还需做下面操作
  <br>
  <figure class="highlight bash">
    <table>
      <tr>
        <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td>
        <td class="code"><pre><span class="line">iptables-save &gt; /etc/iptables</span><br><span class="line"><span class="built_in">echo</span> <span class="string">"iptables-restore /etc/iptables"</span> &gt;&gt; /etc/rc.local</span><br><span class="line"><span class="built_in">echo</span> <span class="string">"/usr/local/sbin/xl2tpd -D &amp;"</span> &gt;&gt; /etc/rc.local</span><br><span class="line">chkconfig --add ipsec</span><br><span class="line">chkconfig --level <span class="number">2345</span> ipsec on</span><br></pre></td>
      </tr>
    </table>
  </figure>
</p>
<p>参考文章：
  <br><a href="http://longtimenoc.com/archives/centos%E4%B8%8Al2tp%E5%AE%89%E8%A3%85%E4%B8%8E%E9%85%8D%E7%BD%AE" title="CentOS上L2TP安装与配置" target="_blank" rel="external">CentOS上L2TP安装与配置</a></p>]]></content>
    <summary type="html">
    <![CDATA[<p>换了个新vps，之前一直用pptp和openvpn，这次准备尝试下l2tp，记录下安装过程</p>
<p>ip里也就能通过NCSetting快速启动vpn了，openvpn没有在NCSetting里的设置
  <br><img src="http://img.xfeng.me/yupoo/C9oEw4OC.jpg!medium" alt="L2TP VPN">
  <br>首先需要卸载已安装的openswan，我因为yum install安装的openswan版本有bug，导致我折腾一天也没连接成功，所以建议直接下载指定版本的源码编译安装</p>
<h3 id="u5B89_u88C5ipsec"><a href="#u5B89_u88C5ipsec" class="headerlink" title="安装ipsec"></a>安装ipsec</h3>
<figure class="highlight bash">
  <table>
    <tr>
      <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td>
      <td class="code"><pre><span class="line">yum remove -y openswan</span><br><span class="line">wget http://www.openswan.org/download/openswan-<span class="number">2.6</span>.<span class="number">24</span>.tar.gz</span><br><span class="line">tar zxvf openswan-<span class="number">2.6</span>.<span class="number">24</span>.tar.gz</span><br><span class="line"><span class="built_in">cd</span> openswan-<span class="number">2.6</span>.<span class="number">24</span></span><br><span class="line">make programs install</span><br></pre></td>
    </tr>
  </table>
</figure>]]>
    
    </summary>
    
      <category term="VPN" scheme="http://xfeng.me/tags/vpn/"/>
    
      <category term="l2tp" scheme="http://xfeng.me/tags/l2tp/"/>
    
      <category term="Linux" scheme="http://xfeng.me/category/linux/"/>
    
      <category term="Notes" scheme="http://xfeng.me/category/linux/notes/"/>
    
  </entry>
  
</feed>
