<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>command line on I Code It</title>
    <link>https://icodeit.org/categories/command-line/</link>
    <description>Recent content in command line on I Code It</description>
    <generator>Hugo -- gohugo.io</generator>
    <lastBuildDate>Sun, 01 Mar 2015 00:00:00 +0000</lastBuildDate><atom:link href="https://icodeit.org/categories/command-line/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>基于inotify的告警脚本</title>
      <link>https://icodeit.org/2015/03/build-monitor-script-based-on-inotify/</link>
      <pubDate>Sun, 01 Mar 2015 00:00:00 +0000</pubDate>
      
      <guid>https://icodeit.org/2015/03/build-monitor-script-based-on-inotify/</guid>
      <description>自动告警脚本 最近项目上有这样一个需求：系统中有一个后台服务会不断的生成监控日志，根据系统的运行情况，它每天会在目录/var/alarms下生成一个文件，文件名带有时间戳，其中内容格式如下：
$ cat /var/alarms/alarms-20150228130522.csv node,summary,occurrence,proiority VIQ002,heartbeat failure,2/12/2015 01:23 AM,critical VIQ002,packages are rejected,2/12/2015 01:22 AM,major VIQ002,connection cannot be established,2/11/2015 01:23 AM,medium VIQ001,packages are rejected,2/11/2015 01:23 AM,warning VIQ001,connection cannot be established,2/09/2015 01:23 AM,medium ... 运维团队需要监控这个目录，如果里边的文件发生了变化，就要及时的发送邮件给工程团队解决。我们当然不可能人工的监控该目录，然后编写邮件，再拷贝粘贴，所以需要编写一个脚本来自动化这个任务。
处理方法有两种：
 编写一个crontab的任务，每隔五分钟轮询一下，然后编写脚本来探测变化，发送邮件 使用操作系统提供的inotify相关API探测变化，编写脚本发送邮件  不过作为程序员，第二种方法显然更高级一些。另外相对于检测文件变化（对比目录树，检查时间戳，而且还要记录上一次变更的状态等），编写一个发送邮件的脚本要简单得多。
使用inotify 如果在Linux下，我们可以使用inotify相关的工具，你可以使用你正在使用的系统下的包管理工具来安装。也可以直接从源码包编译安装。
安装之后，系统中就有了一个叫做inotifywait的命令，这个命令提供多个参数。默认的inotifywait在接收到指定的事件（文件变化）后，会打印信息并退出。可以使用-m参数让inotifywati处于监听状态。-e参数指定需要监听的事件类型，下面是几个常见的事件类型：
 CREATE，创建 MODIFY，修改 CLOSE_WRITE,CLOSE，写入成功  还可以通过--format来指定事件的输出，%w表示监控的文件名，%f表示如果被监控的对象是目录，则当发生事件时返回文件名。比如下面的命令：
$ inotifywait -m -e close_write /var/alarms --format &amp;#34;%w%f&amp;#34; 表示以监控模式（事件发生后不退出，继续监听），监听close_write事件，在/var/alarms目录上，并且输出的格式为%w%f。
这样我们在另一个窗口上模拟事件发生：
$ touch /var/alarms/alarms-20150228130522.csv 当前的窗口就会出现/var/alarms/alarms-20150228130522.csv这样的输出。有了这个功能，我们只需要编写一段简单的脚本就可以完成上一小节中的问题了：
#!/bin/bash DIR=$1 inotifywait -m -e close_write $DIR --format &amp;#34;%w%f&amp;#34; | while read FILE do cat ${FILE} | mail -s &amp;#34;Alarm: $FILE&amp;#34; juntao.</description>
      <content:encoded><![CDATA[<h2 id="自动告警脚本">自动告警脚本</h2>
<p>最近项目上有这样一个需求：系统中有一个后台服务会不断的生成监控日志，根据系统的运行情况，它每天会在目录<code>/var/alarms</code>下生成一个文件，文件名带有时间戳，其中内容格式如下：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ cat /var/alarms/alarms-20150228130522.csv
node,summary,occurrence,proiority
VIQ002,heartbeat failure,2/12/2015 01:23 AM,critical
VIQ002,packages are rejected,2/12/2015 01:22 AM,major
VIQ002,connection cannot be established,2/11/2015 01:23 AM,medium
VIQ001,packages are rejected,2/11/2015 01:23 AM,warning
VIQ001,connection cannot be established,2/09/2015 01:23 AM,medium
...
</code></pre></div><p>运维团队需要监控这个目录，如果里边的文件发生了变化，就要及时的发送邮件给工程团队解决。我们当然不可能人工的监控该目录，然后编写邮件，再拷贝粘贴，所以需要编写一个脚本来自动化这个任务。</p>
<p>处理方法有两种：</p>
<ol>
<li>编写一个crontab的任务，每隔五分钟轮询一下，然后编写脚本来探测变化，发送邮件</li>
<li>使用操作系统提供的<code>inotify</code>相关API探测变化，编写脚本发送邮件</li>
</ol>
<p>不过作为程序员，第二种方法显然更高级一些。另外相对于检测文件变化（对比目录树，检查时间戳，而且还要记录上一次变更的状态等），编写一个发送邮件的脚本要简单得多。</p>
<h3 id="使用inotify">使用inotify</h3>
<p>如果在<code>Linux</code>下，我们可以使用<code>inotify</code>相关的工具，你可以使用你正在使用的系统下的包管理工具来安装。也可以直接从源码包编译安装。</p>
<p>安装之后，系统中就有了一个叫做<code>inotifywait</code>的命令，这个命令提供多个参数。默认的<code>inotifywait</code>在接收到指定的事件（文件变化）后，会打印信息并退出。可以使用<code>-m</code>参数让<code>inotifywati</code>处于监听状态。<code>-e</code>参数指定需要监听的事件类型，下面是几个常见的事件类型：</p>
<ol>
<li><code>CREATE</code>，创建</li>
<li><code>MODIFY</code>，修改</li>
<li><code>CLOSE_WRITE,CLOSE</code>，写入成功</li>
</ol>
<p>还可以通过<code>--format</code>来指定事件的输出，<code>%w</code>表示监控的文件名，<code>%f</code>表示如果被监控的对象是目录，则当发生事件时返回文件名。比如下面的命令：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ inotifywait -m -e close_write /var/alarms --format <span class="s2">&#34;%w%f&#34;</span>
</code></pre></div><p>表示以监控模式（事件发生后不退出，继续监听），监听<code>close_write</code>事件，在<code>/var/alarms</code>目录上，并且输出的格式为<code>%w%f</code>。</p>
<p>这样我们在另一个窗口上模拟事件发生：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ touch /var/alarms/alarms-20150228130522.csv 
</code></pre></div><p>当前的窗口就会出现<code>/var/alarms/alarms-20150228130522.csv</code>这样的输出。有了这个功能，我们只需要编写一段简单的脚本就可以完成上一小节中的问题了：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh"><span class="cp">#!/bin/bash
</span><span class="cp"></span><span class="nv">DIR</span><span class="o">=</span><span class="nv">$1</span>

inotifywait -m -e close_write <span class="nv">$DIR</span> --format <span class="s2">&#34;%w%f&#34;</span> <span class="p">|</span> <span class="k">while</span> <span class="nb">read</span> FILE
<span class="k">do</span>
	cat <span class="si">${</span><span class="nv">FILE</span><span class="si">}</span> <span class="p">|</span> mail -s <span class="s2">&#34;Alarm: </span><span class="nv">$FILE</span><span class="s2">&#34;</span> juntao.qiu@gmail.com
<span class="k">done</span>
</code></pre></div><p>命令<code>mail</code>是Linux下默认的邮件客户端，可以完成邮件的发送功能。将上边的脚本命名为<code>monitor.sh</code>，添加可执行权限，并启动监控：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ chmod +x monitor.sh
$ ./monitor.sh /var/alarms
</code></pre></div><p>这样，当目标目录<code>/var/alarms</code>发生变化后，我们就可以收到告警邮件了！</p>
<h3 id="mac-osx下使用fswatch">Mac OSX下使用fswatch</h3>
<p>如果是在<code>Mac OSX</code>下，虽然没有了<code>inotify</code>相关的API，但是我们可以使用<code>fswatch</code>来完成同样的工作。</p>
<p>使用<code>brew</code>安装<code>fswatch</code>：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ brew install fswatch
</code></pre></div><p>即可。<code>fswatch</code>也有很多选项，我们这里仅使用<code>-0</code>（表示以传统的NUL作为字符串终结符，因为*nix下文件名可以包含任意字符，比如空格）。我们可以很容易的用<code>xargs</code>将检测到的事件进行进一步的处理：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">fswatch -0 /var/alarms <span class="p">|</span> xargs -0 -n <span class="m">1</span> ~/bin/send-notify.sh
</code></pre></div><p>其中，<code>-0</code>的意思与<code>fswatch</code>的命令中的<code>-0</code>一致，<code>-n 1</code>表示每条<code>NUL</code>结尾的字符串都执行一次脚本。脚本<code>send-notify.sh</code>的内容如下：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh"><span class="cp">#!/bin/bash
</span><span class="cp"></span>
<span class="nv">FILE</span><span class="o">=</span><span class="nv">$1</span>
cat <span class="nv">$FILE</span> <span class="p">|</span> mail -s <span class="s2">&#34;Alarm: </span><span class="nv">$FILE</span><span class="s2">&#34;</span> jutao.qiu@gmail.com
</code></pre></div><p>这样，当文件发生变化时，脚本就会发送一封邮件到指定邮箱了（由于我自己的laptop的hostname不像是一个合理的主机名，所以Gmail会把这封邮件放到垃圾邮件列表中，这里只是用作示例而已）。</p>
<p><img loading="lazy" src="/images/2015/03/mail-resized.png" type="" alt="fswatch"  /></p>
<p>当然，由于脚本是我们自己可以编写的，所以理论上当检测到变化之后，我们可以做任何事情，比如<a href="http://icodeit.org/2014/09/simple-idea-and-simple-script/">说几句话</a>，播放一段音乐等。</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>制作一个多彩的svn diff脚本</title>
      <link>https://icodeit.org/2015/02/make-a-colorful-svn-diff/</link>
      <pubDate>Wed, 18 Feb 2015 00:00:00 +0000</pubDate>
      
      <guid>https://icodeit.org/2015/02/make-a-colorful-svn-diff/</guid>
      <description>Code Review 在ThoughtWorks，我们几乎每天都会进行一个叫code review或者code diff的活动：每天下午5:00，团队成员围坐在一起，将今天的修改大概过一下，这样做的好处非常明显：
 分享业务知识，了解彼此的工作 分享技术细节，比如有人使用了某种设计模式 帮助别人发现问题，比如逻辑错误等，群策群力  经过实践，code reivew可以快速发现问题，而且可以尽可能多的分享知识，是一种ThoughtWorker们喜闻乐见的学习/娱乐形式。
但是随着项目的不同，各个团队使用的版本管理工具都不一样。用惯了git的非常漂亮的diff子命令之后，svn的diff简直就是战五渣。没有高亮，没有进度条，就是黑底白字的一些文本，实在无法让人提起兴趣。
这篇文章分享一个简单的方法，可以让你很容易的把svn的diff打造成一个漂亮的工具：
diff格式 Diff是一种通用的表示文本差异的格式，细节可以看我之前写过一篇关于diff和patch的文章。需要说明的是，它作为一种标准格式，很多编辑器都提供对这种格式的高亮显示，比如现在非常流行的Sublime Text编辑器：
默认的，svn的diff命令会生成这样朴素的输出：
命令行的diff高亮显示 在Mac下，可以通过brew来安装一个命令行工具，这个工具可以将Diff格式高亮显示：
$ brew install colordiff 有了这个工具，就可以将svn生成的Diff格式高亮显示出来：
$ svn diff | colordiff 但是你可能已经发现这些神奇的^M，这是Windows系统中的换行符在Unix类系统中的展示，我们需要将Diff先转换一次：
$ svn diff | dos2unix | colordiff 如果你的系统中没有dos2unix，可以用brew来安装：
$ brew install dos2unix unix2dos 分页器 *nix系统下有两种分页器：more和less，less比more的功能更丰富。less有很多的参数，我们这里选用了3个常见的：
 -s: 压缩连续的空白行为一行 -M: 给出更多的提示信息，包含行号，百分比等 +Gg: 先跳至要查看文件的末尾，再跳至文件开头，这样从less就可以得到整个流的长度，从而计算出正确的百分比。当然如果是单独文件时，less是明确知道文件长度的，但是如果是从流中重定向过来的文本，less无法在开始时就得知长度。  下面这条命令可以将当前目录下的所有html文件分屏显示，并且在每一屏的最后一行显示百分比等信息：
$ cat *.html | less -s -M +Gg 放在一起 好了，我们将每个部分都已经讲解了一遍了，现在让我们将这些零件串起来，在svn的working copy中执行这条命令就可以得到非常漂亮的，分页显示的Diff：
$ svn diff | dos2unix | colordiff | less -s -M +Gg 当然，还可以用一个alias(别名)来节省敲入的字符数：</description>
      <content:encoded><![CDATA[<h3 id="code-review">Code Review</h3>
<p>在<code>ThoughtWorks</code>，我们几乎每天都会进行一个叫<code>code review</code>或者<code>code diff</code>的活动：每天下午5:00，团队成员围坐在一起，将今天的修改大概过一下，这样做的好处非常明显：</p>
<ol>
<li>分享业务知识，了解彼此的工作</li>
<li>分享技术细节，比如有人使用了某种设计模式</li>
<li>帮助别人发现问题，比如逻辑错误等，群策群力</li>
</ol>
<p>经过实践，<code>code reivew</code>可以快速发现问题，而且可以尽可能多的分享知识，是一种<code>ThoughtWorker</code>们喜闻乐见的学习/娱乐形式。</p>
<p>但是随着项目的不同，各个团队使用的版本管理工具都不一样。用惯了<code>git</code>的非常漂亮的<code>diff</code>子命令之后，<code>svn</code>的<code>diff</code>简直就是战五渣。没有高亮，没有进度条，就是黑底白字的一些文本，实在无法让人提起兴趣。</p>
<p>这篇文章分享一个简单的方法，可以让你很容易的把<code>svn</code>的<code>diff</code>打造成一个漂亮的工具：</p>
<p><img loading="lazy" src="/images/2015/02/svn-color-diff-resized.png" type="" alt="svn diff"  /></p>
<h4 id="diff格式">diff格式</h4>
<p>Diff是一种通用的表示文本差异的格式，细节可以看我之前写过一篇<a href="http://icodeit.org/2012/02/diff%E5%92%8Cpatch%E7%9A%84%E4%BD%BF%E7%94%A8%E4%BB%8B%E7%BB%8D/">关于diff和patch的文章</a>。需要说明的是，它作为一种标准格式，很多编辑器都提供对这种格式的高亮显示，比如现在非常流行的<code>Sublime Text</code>编辑器：</p>
<p><img loading="lazy" src="/images/2015/02/sublime-diff-resized.png" type="" alt="sublime diff"  /></p>
<p>默认的，<code>svn</code>的diff命令会生成这样<strong>朴素</strong>的输出：</p>
<p><img loading="lazy" src="/images/2015/02/svn-diff-resized.png" type="" alt="svn diff"  /></p>
<h4 id="命令行的diff高亮显示">命令行的diff高亮显示</h4>
<p>在Mac下，可以通过<code>brew</code>来安装一个命令行工具，这个工具可以将<code>Diff</code>格式高亮显示：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ brew install colordiff
</code></pre></div><p>有了这个工具，就可以将<code>svn</code>生成的<code>Diff</code>格式高亮显示出来：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ svn diff <span class="p">|</span> colordiff
</code></pre></div><p><img loading="lazy" src="/images/2015/02/color-diff-resized.png" type="" alt="color diff"  /></p>
<p>但是你可能已经发现这些神奇的<code>^M</code>，这是<code>Windows</code>系统中的换行符在<code>Unix</code>类系统中的展示，我们需要将<code>Diff</code>先转换一次：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ svn diff <span class="p">|</span> dos2unix <span class="p">|</span> colordiff
</code></pre></div><p><img loading="lazy" src="/images/2015/02/color-diff-converted-resized.png" type="" alt="color diff converted"  /></p>
<p>如果你的系统中没有<code>dos2unix</code>，可以用<code>brew</code>来安装：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ brew install dos2unix unix2dos
</code></pre></div><h4 id="分页器">分页器</h4>
<p>*nix系统下有两种分页器：<code>more</code>和<code>less</code>，<code>less</code>比<code>more</code>的功能更丰富。<code>less</code>有很多的参数，我们这里选用了3个常见的：</p>
<ol>
<li><code>-s</code>: 压缩连续的空白行为一行</li>
<li><code>-M</code>: 给出更多的提示信息，包含行号，百分比等</li>
<li><code>+Gg</code>: 先跳至要查看文件的末尾，再跳至文件开头，这样从less就可以得到整个流的长度，从而计算出正确的百分比。当然如果是单独文件时，less是明确知道文件长度的，但是如果是从流中重定向过来的文本，less无法在开始时就得知长度。</li>
</ol>
<p>下面这条命令可以将当前目录下的所有<code>html</code>文件分屏显示，并且在每一屏的最后一行显示百分比等信息：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ cat *.html <span class="p">|</span> less -s -M +Gg
</code></pre></div><h4 id="放在一起">放在一起</h4>
<p>好了，我们将每个部分都已经讲解了一遍了，现在让我们将这些零件串起来，在svn的<code>working copy</code>中执行这条命令就可以得到非常漂亮的，分页显示的Diff：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ svn diff <span class="p">|</span> dos2unix <span class="p">|</span> colordiff <span class="p">|</span> less -s -M +Gg
</code></pre></div><p>当然，还可以用一个<code>alias</code>(别名)来节省敲入的字符数：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ <span class="nb">alias</span> <span class="nv">sd</span><span class="o">=</span><span class="s1">&#39;svn diff | dos2unix | colordiff | less -s -M +Gg&#39;</span>
</code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>Linux命令行中的7个小技巧</title>
      <link>https://icodeit.org/2015/02/linux-tips/</link>
      <pubDate>Sat, 14 Feb 2015 00:00:00 +0000</pubDate>
      
      <guid>https://icodeit.org/2015/02/linux-tips/</guid>
      <description>Linux命令行中的7个小技巧 命令行是开发者的好朋友，*nix系统（包括Mac OS X和各种Linux）都自带了强大的Shell环境，作为一个专业的程序员，Shell是离不开的。这里总结了几个常用的小技巧，都是我自己平时经常用，而又不想每次都去Google的。
如何知道哪个进程在监听4000端口？ 当启动服务时，经常会遇到想要Address already in use这样的异常，那么如何知道是哪个进程占用了该端口呢？
$ lsof -i :4000 lsof会列出系统目前打开的文件（List open files，Linux世界中，一切都是文件），-i表示网络地址（Internet address），注意此处的冒号。如果不带参数，lsof会列出所有打开的网络地址：
$ lsof -i :4000 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME ruby 32303 jtqiu 7u IPv4 0x947b402a4bb8370b 0t0 TCP *:terabase (LISTEN) Shell中如何设置代理？ 很多公司都会有一个代理服务器供员工上外网使用，命令行中设置代理非常容易：
export http_proxy=&amp;#34;http://username:password@hosename:port&amp;#34; 如果密码中有特设字符，比如$的话，需要转义一下。使用URLEncoding即可，比如$就是%24。最简单的就是在Chrome的Console中输入encodeURIComponent(&amp;quot;$&amp;quot;)来获得转义字符。
如果不想对某些地址使用代理，可以设置no_proxy环境变量：
export no_proxy=&amp;#34;127.0.0.1, localhost, *.cnn.com, 192.168.1.10, domain.com:8080&amp;#34; 如何为svn中的脚本设置可执行属性 你在Linux下创建了一个可执行脚本e2e_test.sh，但是团队里的其他人工作在Windows系统上，当你提交可执行脚本之后，他们checkout的是一个不能执行的文件！（其实也在情理之中，Windows这种垃圾货什么时候正常过呢？）
这时候可以通过给这个脚本设置一个svn的属性:
svn propset svn:executable &amp;#34;*&amp;#34; e2e_test.sh 这样在Windows上才heckout之后就正常了。
在Bash脚本中如何判断一个文件是否可执行？ 有时候我们在Bash中需要判断某个文件是否可以执行，这行脚本可以解救你：
if [ -x $FILENAME ]; then # the file is executable fi 判断某个文件是否存在的脚本为：</description>
      <content:encoded><![CDATA[<h3 id="linux命令行中的7个小技巧">Linux命令行中的7个小技巧</h3>
<p>命令行是开发者的好朋友，<code>*nix</code>系统（包括Mac OS X和各种Linux）都自带了强大的Shell环境，作为一个专业的程序员，Shell是离不开的。这里总结了几个常用的小技巧，都是我自己平时经常用，而又不想每次都去Google的。</p>
<h4 id="如何知道哪个进程在监听4000端口">如何知道哪个进程在监听4000端口？</h4>
<p>当启动服务时，经常会遇到想要<code>Address already in use</code>这样的异常，那么如何知道是哪个进程占用了该端口呢？</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ lsof -i :4000
</code></pre></div><p><code>lsof</code>会列出系统目前打开的文件（List open files，Linux世界中，一切都是文件），<code>-i</code>表示网络地址（Internet address），注意此处的冒号。如果不带参数，lsof会列出所有打开的网络地址：</p>
<p><img loading="lazy" src="/images/2015/02/lsof-resized.png" type="" alt="lsof"  /></p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ lsof -i :4000
COMMAND   PID  USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ruby    <span class="m">32303</span> jtqiu    7u  IPv4 0x947b402a4bb8370b      0t0  TCP *:terabase <span class="o">(</span>LISTEN<span class="o">)</span>
</code></pre></div><h4 id="shell中如何设置代理">Shell中如何设置代理？</h4>
<p>很多公司都会有一个代理服务器供员工上外网使用，命令行中设置代理非常容易：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh"><span class="nb">export</span> <span class="nv">http_proxy</span><span class="o">=</span><span class="s2">&#34;http://username:password@hosename:port&#34;</span>
</code></pre></div><p>如果密码中有特设字符，比如<code>$</code>的话，需要转义一下。使用URLEncoding即可，比如<code>$</code>就是<code>%24</code>。最简单的就是在Chrome的<code>Console</code>中输入<code>encodeURIComponent(&quot;$&quot;)</code>来获得转义字符。</p>
<p>如果不想对某些地址使用代理，可以设置<code>no_proxy</code>环境变量：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh"><span class="nb">export</span> <span class="nv">no_proxy</span><span class="o">=</span><span class="s2">&#34;127.0.0.1, localhost, *.cnn.com, 192.168.1.10, domain.com:8080&#34;</span>
</code></pre></div><h4 id="如何为svn中的脚本设置可执行属性">如何为svn中的脚本设置可执行属性</h4>
<p>你在Linux下创建了一个可执行脚本<code>e2e_test.sh</code>，但是团队里的其他人工作在Windows系统上，当你提交可执行脚本之后，他们checkout的是一个不能执行的文件！（其实也在情理之中，Windows这种垃圾货什么时候正常过呢？）</p>
<p>这时候可以通过给这个脚本设置一个<code>svn</code>的属性:</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">svn propset svn:executable <span class="s2">&#34;*&#34;</span> e2e_test.sh
</code></pre></div><p>这样在Windows上才heckout之后就正常了。</p>
<h4 id="在bash脚本中如何判断一个文件是否可执行">在Bash脚本中如何判断一个文件是否可执行？</h4>
<p>有时候我们在<code>Bash</code>中需要判断某个文件是否可以执行，这行脚本可以解救你：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh"><span class="k">if</span> <span class="o">[</span> -x <span class="nv">$FILENAME</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
  <span class="c1"># the file is executable</span>
<span class="k">fi</span>
</code></pre></div><p>判断某个文件是否存在的脚本为：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh"><span class="k">if</span> <span class="o">[</span> -f <span class="nv">$FILENAME</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
  <span class="c1"># the file is existing</span>
<span class="k">fi</span>
</code></pre></div><h4 id="我正在用的linux是哪个发行版">我正在用的Linux是哪个发行版？</h4>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ lsb_release -a
</code></pre></div><p>在<code>SUSE</code>系统中运行这条命令可以得到这样的输出:</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ lsb_release -a
LSB Version:    core-2.0-noarch:core-3.0-noarch:core-2.0-x86_64:core-3.0-x86_64:desktop-3.1-amd64:desktop-3.1-noarch:graphics-2.0-amd64:graphics-2.0-noarch:graphics-3.1-amd64:graphics-3.1-noarch
Distributor ID: SUSE LINUX
Description:    SUSE Linux Enterprise Server <span class="m">10</span> <span class="o">(</span>x86_64<span class="o">)</span>
Release:        <span class="m">10</span>
Codename:       n/a
</code></pre></div><p>而在<code>ubuntu</code>上则为:</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ lsb_release  -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 12.04.3 LTS
Release:        12.04
Codename:       precise
</code></pre></div><p>与之相关的还有个问题是我当前的操作系统是<code>32位还是64为呢</code>?</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ uname -m
x86_64
</code></pre></div><p>或者使用<code>file</code>命令来查看系统自带的执行文件的元数据信息:</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ file /usr/bin/file
/usr/bin/file: ELF 64-bit LSB executable, x86-64, version <span class="m">1</span> <span class="o">(</span>SYSV<span class="o">)</span>, dynamically linked <span class="o">(</span>uses shared libs<span class="o">)</span>, <span class="k">for</span> GNU/Linux 2.6.15, BuildID<span class="o">[</span>sha1<span class="o">]=</span>0xe04b36145abc21d863652b93e6a0d069f7dfd3f4, stripped
</code></pre></div><h4 id="查找文件跳过某些指定目录">查找文件(跳过某些指定目录)</h4>
<p>你想要统计系统中所有的<code>JavaScript</code>文件的数量，但是又不想把外部的库文件（位于<code>libs</code>目录中）统计在内：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">find . -path ./libs -prune -o -name <span class="s2">&#34;*.js&#34;</span> <span class="p">|</span> wc -l
</code></pre></div><p>这里大概解释一下，上面的命令其实等于这条命令的缩写：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">find . -path ./libs -a -prune -o -name <span class="s2">&#34;*.js&#34;</span> <span class="p">|</span> wc -l
</code></pre></div><p>也即</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">find . -path ./libs -and -prune -or -name <span class="s2">&#34;*.js&#34;</span> <span class="p">|</span> wc -l
</code></pre></div><p>翻译成伪代码相当于：</p>
<div class="highlight"><pre class="chroma"><code class="language-ruby" data-lang="ruby"><span class="k">if</span> <span class="n">path</span> <span class="o">==</span> <span class="s2">&#34;./libs&#34;</span>
    <span class="n">prune</span>
<span class="k">else</span>
    <span class="n">find_by_name</span> <span class="s2">&#34;*.js&#34;</span>
<span class="k">end</span>
</code></pre></div><h4 id="断点续传">断点续传</h4>
<p>下载了一半，网络断了。小文件的话大不了重来一次，但是如果是一个7G的镜像呢？好在我们有<code>wget -c</code>。<code>wget</code>基本上是Linux中下载软件的标配了，它有很多的参数，甚至可以将整个静态网站克隆到本地，断点续传当然是支持的了：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ wget -c https://downloads.cloudera.com/demo_vm/virtualbox/cloudera-quickstart-vm-4.6.0-0-virtualbox.7z --no-check-certificate
--2014-05-08 12:32:25--  https://downloads.cloudera.com/demo_vm/virtualbox/cloudera-quickstart-vm-4.6.0-0-virtualbox.7z
Connecting to 172.19.6.47:8080... connected.
Proxy request sent, awaiting response... <span class="m">206</span> Partial Content
Length: <span class="m">3393638045</span> <span class="o">(</span>3.2G<span class="o">)</span>, <span class="m">2951427152</span> <span class="o">(</span>2.7G<span class="o">)</span> remaining <span class="o">[</span>text/plain<span class="o">]</span>
Saving to: <span class="sb">`</span>cloudera-quickstart-vm-4.6.0-0-virtualbox.7z<span class="err">&#39;</span>

13% <span class="o">[</span>++++++++++                                                                      <span class="o">]</span> 450,866,893 57.8K/s  eta 3h 57m
</code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>svn中的分支管理</title>
      <link>https://icodeit.org/2014/08/how-to-merge-branches-in-svn/</link>
      <pubDate>Mon, 25 Aug 2014 00:00:00 +0000</pubDate>
      
      <guid>https://icodeit.org/2014/08/how-to-merge-branches-in-svn/</guid>
      <description>分支策略 本来准备整理一篇版本管理中，关于分支的维护策略。后来看到阮一峰老师的这篇文章，觉得非常清晰，这里给出一个链接供参考。
另外一个有意思的链接在这里，也可以一并参看。
本文就仅仅简单的描述一下，使用svn的命令行工具，如何具体完成合并的操作：
在Svn中合并分支 在svn中，要合并两个分支（通常是将某个分支b合并到trunk上，不过另一种模式下也可以将trunk合并到b上）非常简单，我们以一个简单的例子来说明其步骤。
比如我们要将trunk上的修改合并到分支b上，操作可以分为4步：
 切换到分支b上（之前执行过svn co /path/branches/b之后的目录） 使用svn log --stop-on-copy命令得到该分支的最早版本号 使用svn merge --dry-run -rXXX:HEAD /path/trunk来预览合并列表 合并  在第二步中，一个典型的输出是这样的：
$ svn log --stop-on-copy ... r231625 | juntao | 2014-07-10 13:33:36 +1000 (Thu, 10 Jul 2014) | 1 line Juntao Change the version in pom.xml ------------------------------------------------------------------------ r231623 | abruzzi | 2014-07-10 13:22:00 +1000 (Thu, 10 Jul 2014) | 1 line Spike on data structure of c-wifi, a workable prototype ------------------------------------------------------------------------ r231610 | juntao | 2014-07-10 12:29:01 +1000 (Thu, 10 Jul 2014) | 1 line Create a new branch for c-wifi ------------------------------------------------------------------------ 一旦有了这个修订号(231610)，就可以开始合并了：</description>
      <content:encoded><![CDATA[<h3 id="分支策略">分支策略</h3>
<p>本来准备整理一篇版本管理中，关于分支的维护策略。后来看到阮一峰老师的<a href="http://www.ruanyifeng.com/blog/2012/07/git.html">这篇文章</a>，觉得非常清晰，这里给出一个链接供参考。</p>
<p>另外一个有意思的<a href="http://codicesoftware.blogspot.com/2008/08/4-steps-to-make-version-control-shine.html">链接在这里</a>，也可以一并参看。</p>
<p>本文就仅仅简单的描述一下，使用svn的命令行工具，如何具体完成合并的操作：</p>
<h3 id="在svn中合并分支">在Svn中合并分支</h3>
<p>在svn中，要合并两个分支（通常是将某个分支b合并到trunk上，不过另一种模式下也可以将trunk合并到b上）非常简单，我们以一个简单的例子来说明其步骤。</p>
<p>比如我们要将trunk上的修改合并到分支b上，操作可以分为4步：</p>
<ol>
<li>切换到分支b上（之前执行过<code>svn co /path/branches/b</code>之后的目录）</li>
<li>使用<code>svn log --stop-on-copy</code>命令得到该分支的最早版本号</li>
<li>使用<code>svn merge --dry-run -rXXX:HEAD /path/trunk</code>来预览合并列表</li>
<li>合并</li>
</ol>
<p>在第二步中，一个典型的输出是这样的：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ svn log --stop-on-copy                                                                   
...

r231625 <span class="p">|</span> juntao <span class="p">|</span> 2014-07-10 13:33:36 +1000 <span class="o">(</span>Thu, <span class="m">10</span> Jul 2014<span class="o">)</span> <span class="p">|</span> <span class="m">1</span> line

Juntao Change the version in pom.xml
------------------------------------------------------------------------
r231623 <span class="p">|</span> abruzzi <span class="p">|</span> 2014-07-10 13:22:00 +1000 <span class="o">(</span>Thu, <span class="m">10</span> Jul 2014<span class="o">)</span> <span class="p">|</span> <span class="m">1</span> line

Spike on data structure of c-wifi, a workable prototype
------------------------------------------------------------------------
r231610 <span class="p">|</span> juntao <span class="p">|</span> 2014-07-10 12:29:01 +1000 <span class="o">(</span>Thu, <span class="m">10</span> Jul 2014<span class="o">)</span> <span class="p">|</span> <span class="m">1</span> line

Create a new branch <span class="k">for</span> c-wifi
------------------------------------------------------------------------
</code></pre></div><p>一旦有了这个修订号(231610)，就可以开始合并了：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ svn merge --dry-run -r231610:HEAD /path/trunk
</code></pre></div><p>这个命令会列出从修订好r231610到当前版本之中，trunk和分支b之间的所有需要合并的文件列表：</p>
<pre><code>--- Merging r235763 through r236311 into 'src/test/java':
U    src/test/java/tcom/checkout/CheckoutServiceTest.java
U    src/test/java/bundles/checkout/accordion/AppointmentTest.java
U    src/test/java/common/service/ServiceHandlerTest.java
...
Summary of conflicts:
  Text conflicts: 2
</code></pre><p>最后，svn会给出冲突信息（如果有的话），这时，我们来决定是否合并，以及合并哪些修订号区间的修改。如果预览之后觉得可以直接合并，则可以直接运行：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ svn merge -r231610:HEAD /path/trunk
</code></pre></div><p>过程中，遇到冲突的情况，svn会询问采取哪种方式来处理</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">Select: <span class="o">(</span>p<span class="o">)</span> postpone, <span class="o">(</span>df<span class="o">)</span> diff-full, <span class="o">(</span>e<span class="o">)</span> edit,
        <span class="o">(</span>mc<span class="o">)</span> mine-conflict, <span class="o">(</span>tc<span class="o">)</span> theirs-conflict,
        <span class="o">(</span>s<span class="o">)</span> show all options: p
</code></pre></div><p>如果拿不准，可以使用<code>p</code>子命令，然后等到最后在IDE或者编辑器中合并，如果想要丢弃自己的修改，使用<code>tc</code>子命令；如果要丢弃别人的修改，使用<code>mc</code>子命令。</p>
<p>最后，在编辑器中修改完了这些冲突之后，使用:</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ svn resolved pom.xml
Resolved conflicted state of <span class="s1">&#39;pom.xml&#39;</span>
</code></pre></div><p>来标记该冲突已经被解决。最后，运行测试并提交本次修改：</p>
<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ mvn clean <span class="nb">test</span>
$ svn ci -m <span class="s2">&#34;Merge branch b with trunk&#34;</span>
</code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>ssh forward 101</title>
      <link>https://icodeit.org/2012/10/using-ssh-forward-to-get-out-of-stupid-wall/</link>
      <pubDate>Thu, 25 Oct 2012 00:00:00 +0000</pubDate>
      
      <guid>https://icodeit.org/2012/10/using-ssh-forward-to-get-out-of-stupid-wall/</guid>
      <description>Generate the public and private key pair This step is quite strightforward, just generate the keys by using ssh-keygen: $ ssh-keygen #specify the key file name (I use the id_ plus remote site hostname) then you&amp;rsquo;ll get 2 keys locally, you can do this step in any place, but people do it on their home-dir/.ssh, after the creation, you need to change the mask of the key file: $ chmod 600 id_site</description>
      <content:encoded><![CDATA[<h2 id="generate-the-public-and-private-key-pair">Generate the public and private key pair</h2>
<p>This step is quite strightforward, just generate the keys by using ssh-keygen:
$ ssh-keygen #specify the key file name (I use the id_ plus remote site hostname)
then you&rsquo;ll get 2 keys locally, you can do this step in any place, but people do it
on their home-dir/.ssh, after the creation, you need to change the mask of the key file:
$ chmod 600 id_site</p>
<h2 id="put-the-public-key-remotely">Put the public key remotely</h2>
<p>Okay, once the key is generated, we can simply put the publick key to remote site, and we
don&rsquo;t need to type password any more:
$ scp id_site.pub user@remote:
Note the colon at the end of the command above, login to remote server
# cat id_site.pub &raquo; .ssh/authorized_keys
# rm id_site.pub
Then go back local machine, and we&rsquo;re done</p>
<h2 id="ssh-forward">SSH forward</h2>
<p>Now we can simply login the remote server by using the private key just generated:
$ ssh -i id_site user@remote</p>
<p>You then probably be noticed to add the key to system key chain, it is on Mac. And we now don&rsquo;t
need to type the password manually. So let&rsquo;s go a little bit further:
$ ssh -N -i id_site -l 15100:localhost:15100 user@remote</p>
<p>Then you can access the localhost:1500 port on remote machine BY using the local port, that&rsquo;s why it
called ssh forward I think.</p>
<p>You may note that I&rsquo;m using the port 15100, that&rsquo;s the mailcatcher web mananger port, I cannot access
the mailcatcher running on another machine, but somehow, I can ssh it through ssh port(22), so I asked
one of my <em>smart</em> colleagues, and got this solution.</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
