<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>Jeoygin Wang</title>
        <link>http://jeoygin.org</link>
        <description><![CDATA[RSS feed for Jeoygin Wang's blog]]></description>
        <atom:link href="http://jeoygin.org/rss.xml" rel="self"
                   type="application/rss+xml" />
        <lastBuildDate>Sat, 20 Jan 2018 00:00:00 UT</lastBuildDate>
        <item>
    <title>闲话macOS五：实用命令行</title>
    <link>http://jeoygin.org/2018/01/20/customize-macOS-5/</link>
    <description><![CDATA[<div id="primary">
    <div class="inside">
        <h1 class="title">闲话macOS五：实用命令行</h1>
        <div class="opacity08"><small>
                <i>January 20, 2018 / <a href="http://jeoygin.org/label/macos/">macOS</a>, <a href="http://jeoygin.org/label/customization/">customization</a>, <a href="http://jeoygin.org/label/tool/">tool</a>, <a href="http://jeoygin.org/label/shell/">shell</a></i>
        </small></div>
        <br>
        <p>本文主要介绍我在日常工作和学习中常用的命令行工具。</p>
<h2 id="包管理">包管理</h2>
<p>不难想象，如果没有包管理工具，安装或更新软件时需要下载安装包，然后安装或编译。目前各种Linux发行版基本自带包管理工具，当然macOS也有App Store可以安装应用，但是不能用于安装命令行工具或链接库。幸运的是有第三方工具可以编译、安装和更新命令行或图形界面开源软件，方便了macOS的用户，耳熟能详的有：</p>
<ul>
<li>Homebrew: <a href="https://brew.sh/" class="uri">https://brew.sh/</a></li>
<li>MacPorts: <a href="https://www.macports.org/" class="uri">https://www.macports.org/</a></li>
</ul>
<p>我一直在用的是Homebrew，MacPorts未曾用过，Homebrew基本可以满足大部分需求，受其启发，有热心人士开发了针对Linux系统的Linuxbrew。安装Homebrew很简单，一行命令：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="ex">/usr/bin/ruby</span> -e <span class="st">&quot;</span><span class="va">$(</span><span class="ex">curl</span> -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install<span class="va">)</span><span class="st">&quot;</span></code></pre></div>
<p>Homebrew-Cask扩展了Homebrew，可一键安装macOS应用：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="ex">brew</span> tap caskroom/cask</code></pre></div>
<p>本文后面提到的工具基本都可以用Homebrew安装，tldr：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="ex">brew</span> install tldr</code></pre></div>
<p>除了系统层面的包管理工具，各大编程语言也有语言层面的包管理工具，比如：</p>
<ul>
<li>Node.js的npm: <a href="https://www.npmjs.com/" class="uri">https://www.npmjs.com/</a></li>
<li>Python的pip: <a href="https://pip.pypa.io/en/stable/" class="uri">https://pip.pypa.io/en/stable/</a></li>
<li>Ruby的gem: <a href="https://rubygems.org/" class="uri">https://rubygems.org/</a></li>
</ul>
<p>在语言层面，除了包管理工具，还有版本管理工具，方便在多个版本之间切换，比如：</p>
<ul>
<li>Node.js的nvm: <a href="https://github.com/creationix/nvm" class="uri">https://github.com/creationix/nvm</a></li>
<li>Python的virtualenv和virtualenvwrapper
<ul>
<li><a href="https://virtualenv.pypa.io/en/stable/" class="uri">https://virtualenv.pypa.io/en/stable/</a></li>
<li><a href="https://virtualenvwrapper.readthedocs.io/en/latest/" class="uri">https://virtualenvwrapper.readthedocs.io/en/latest/</a></li>
</ul></li>
<li>Ruby的rvm: <a href="https://rvm.io/" class="uri">https://rvm.io/</a></li>
<li>JVM系列的SDKMAN: <a href="http://sdkman.io/" class="uri">http://sdkman.io/</a></li>
</ul>
<h2 id="辅助">辅助</h2>
<p>命令太多，记不住怎么办？其实有时会突然忘了某个命令的某种用法是常事，用man命令看文档是个好习惯，除此还可用tldr，这是由社区驱动的man页面，提供了多个命令的常见用法，可见<a href="https://github.com/tldr-pages/tldr/tree/master/pages/common" class="uri">https://github.com/tldr-pages/tldr/tree/master/pages/common</a>。</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="ex">tldr</span> tldr

<span class="ex">tldr</span>

<span class="ex">Simplified</span> man pages.

<span class="ex">-</span> Get typical usages of a command (hint: this is how you got here!)<span class="bu">:</span>
    <span class="ex">tldr</span> command

<span class="ex">-</span> Update the local cache of tldr pages:
    <span class="ex">tldr</span> --update</code></pre></div>
<p>另外一个要推荐的工具不可说，当命令打错时，可用来纠正：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="ex">brew</span> instlal thefuck
<span class="ex">Error</span>: Unknown command: instlal
$ <span class="ex">fuck</span>
<span class="ex">brew</span> install thefuck [enter/↑/↓/ctrl+c]</code></pre></div>
<p>Github仓库：</p>
<ul>
<li><a href="https://github.com/tldr-pages/tldr" class="uri">https://github.com/tldr-pages/tldr</a></li>
<li><a href="https://github.com/nvbn/thefuck" class="uri">https://github.com/nvbn/thefuck</a></li>
</ul>
<h2 id="变量与通配符">变量与通配符</h2>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="fu">cp</span> file<span class="dt">{,.bak}</span> <span class="co"># cp file file.bak</span>
$ <span class="fu">mkdir</span> -p test-<span class="dt">{a,b}/subtest-{1,2}</span> <span class="co"># mkdir -p test-a/subtest-1 test-a/subtest-2 test-b/subtest-1 test-b/subtest-2</span>
$ <span class="bu">echo</span> <span class="dt">{1..10}</span>
<span class="ex">1</span> 2 3 4 5 6 7 8 9 10
$ <span class="bu">echo</span> <span class="va">${name:?</span>name is undefined<span class="va">}</span>
<span class="ex">zsh</span>: name: name is undefined
$ <span class="bu">echo</span> <span class="va">${name:-</span>Jeoygin<span class="va">}</span>
<span class="ex">Jeoygin</span>
$ <span class="va">name=</span>test.pdf
$ <span class="bu">echo</span> <span class="va">${name%</span>.pdf<span class="va">}</span>
<span class="bu">test</span>
$ <span class="bu">echo</span> <span class="va">${name#</span>test<span class="va">}</span>
<span class="ex">.pdf</span>
$ <span class="va">name=</span>test.2018.pdf
$ <span class="bu">echo</span> <span class="va">${name%</span>.*<span class="va">}</span>
<span class="ex">test.2018</span>
$ <span class="bu">echo</span> <span class="va">${name%%</span>.*<span class="va">}</span>
<span class="bu">test</span>
$ <span class="bu">echo</span> <span class="va">${name#</span>*.<span class="va">}</span>
<span class="ex">2018.pdf</span>
$ <span class="bu">echo</span> <span class="va">${name##</span>*.<span class="va">}</span>
<span class="ex">pdf</span></code></pre></div>
<h2 id="gnu命令行工具">GNU命令行工具</h2>
<p>macOS的有些命令行工具的用法和Linux版本有些不同（比如sed），另外，macOS原生命令的选项只能位于参数前面，而我个人一些不成熟的小习惯违背了这个约束（比如 <code>rm /path/to/somewhere -rf</code> ）。于是我安装了GNU命令行工具替换macOS的部分原生命令：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="ex">brew</span> install coreutils
$ <span class="ex">brew</span> install gawk
$ <span class="ex">brew</span> install gnu-sed</code></pre></div>
<h2 id="搜索">搜索</h2>
<p>搜索的重要性不用多说了，能帮助我们快速找到想要的数据。</p>
<h3 id="文件名搜索">文件名搜索</h3>
<p>首推系统自带的find：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="fu">find</span> /path/to/dir -iname <span class="st">'*.ext'</span> <span class="co"># 查找指定目录下文件名后缀为.ext的文件</span></code></pre></div>
<p>fd旨在替代find，更加简单、快速和用户友好：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="ex">brew</span> install fd
$ <span class="ex">fd</span> pattern /path/to/dir
$ <span class="ex">fd</span> pattern <span class="co"># 在当前目录下查找</span>
$ <span class="ex">fd</span> <span class="st">'\.ext$'</span></code></pre></div>
<p>Github仓库：</p>
<ul>
<li><a href="https://github.com/sharkdp/fd" class="uri">https://github.com/sharkdp/fd</a></li>
</ul>
<h3 id="内容搜索">内容搜索</h3>
<p>首推系统自带的grep：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="fu">grep</span> -r foo .
$ <span class="fu">ps</span> -ef <span class="kw">|</span> <span class="fu">grep</span> pattern <span class="kw">|</span> <span class="fu">grep</span> -v grep</code></pre></div>
<p>四五年前开始用ack，用起来比grep简单，可忽略.gitignore中的文件，现在常用的是ag（the silver search）。还有用rust实现的rg（ripgrep），号称是速度最快。</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="ex">brew</span> install the_silver_searcher
$ <span class="ex">brew</span> install ripgrep</code></pre></div>
<p>Github仓库：</p>
<ul>
<li><a href="https://github.com/beyondgrep/ack2" class="uri">https://github.com/beyondgrep/ack2</a></li>
<li><a href="https://github.com/ggreer/the_silver_searcher" class="uri">https://github.com/ggreer/the_silver_searcher</a></li>
<li><a href="https://github.com/BurntSushi/ripgrep" class="uri">https://github.com/BurntSushi/ripgrep</a></li>
</ul>
<h3 id="交互式过滤">交互式过滤</h3>
<p>首先来说一下什么是交互式过滤，像上文的grep或ag等是根据给定的关键字或模式对结果进行过滤后全部输出，而交互式过滤是把备选项都列出来，根据你的输入不断减少备选项，少到一定程度就可以用光标或快捷键来选择。</p>
<p>两三年前在Emacs社区里第一次听人说到percol，可谓是交互式过滤的先锋，其作者也开发了一些Emacs包。用过percol后对其爱不释手，但有个问题是需要依赖Python:</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="ex">pip</span> install percol</code></pre></div>
<p>后来知道还有诸如peco、fzy和fzf这些，而Facebook的fpp（PathPicker）更专注于选择路径，可参考<a href="http://www.cnblogs.com/bamanzi/p/cli-narrowing-tools.html" class="uri">http://www.cnblogs.com/bamanzi/p/cli-narrowing-tools.html</a>对比这些工具。目前我在用fzf，一是它用go实现，速度快，二是对readline和tmux支持好。</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="ex">brew</span> install fzf</code></pre></div>
<p><img src="https://i.imgur.com/oYz95NK.gif" /></p>
<p>fzf自带一些使用交互式过滤的功能，比如设置快捷键和自动完成。</p>
<p>fzf设置了如下快捷键：</p>
<ul>
<li><code>CTRL-T</code>: 粘贴选择的文件和目录到命令行</li>
<li><code>CTRL-R</code>: 粘贴选择的历史命令到命令行</li>
<li><code>ALT-C</code>: 进入选择的目录</li>
</ul>
<p>文件和目录自动完成：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="ex">vim</span> **<span class="op">&lt;</span>TAB<span class="op">&gt;</span>
$ <span class="ex">vim</span> ../**<span class="op">&lt;</span>TAB<span class="op">&gt;</span>
$ <span class="ex">vim</span> ../fzf**<span class="op">&lt;</span>TAB<span class="op">&gt;</span>
$ <span class="ex">vim</span> ~/**<span class="op">&lt;</span>TAB<span class="op">&gt;</span>

$ <span class="bu">cd</span> **<span class="op">&lt;</span>TAB<span class="op">&gt;</span>
$ <span class="bu">cd</span> ~/projects/fzf**<span class="op">&lt;</span>TAB<span class="op">&gt;</span></code></pre></div>
<p>进程ID自动完成：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="co"># 可以使用&lt;TAB&gt;或&lt;Shift-TAB&gt;选择多个进程</span>
$ <span class="bu">kill</span> -9 <span class="op">&lt;</span>TAB<span class="op">&gt;</span></code></pre></div>
<p>主机名自动完成：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="fu">ssh</span> **<span class="op">&lt;</span>TAB<span class="op">&gt;</span></code></pre></div>
<p>环境变量/别名自动完成：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="bu">unset</span> **<span class="op">&lt;</span><span class="ex">TAB</span><span class="op">&gt;</span>
$ <span class="bu">export</span> **<span class="op">&lt;</span><span class="ex">TAB</span><span class="op">&gt;</span>
$ <span class="bu">unalias</span> **<span class="op">&lt;</span>TAB<span class="op">&gt;</span></code></pre></div>
<p>Github仓库：</p>
<ul>
<li><a href="https://github.com/mooz/percol" class="uri">https://github.com/mooz/percol</a></li>
<li><a href="https://github.com/peco/peco" class="uri">https://github.com/peco/peco</a></li>
<li><a href="https://github.com/junegunn/fzf" class="uri">https://github.com/junegunn/fzf</a></li>
<li><a href="https://github.com/jhawthorn/fzy" class="uri">https://github.com/jhawthorn/fzy</a></li>
<li><a href="https://github.com/facebook/PathPicker" class="uri">https://github.com/facebook/PathPicker</a></li>
</ul>
<h2 id="目录跳转">目录跳转</h2>
<p>目录间跳转是一个频繁发生的行为，有时为了方便，可能会开多个窗口或标签打开多个目录，把目录跳转问题转变成一个窗口/标签切换问题。但难免还是需要切换目录，这里主要介绍几种更快更智能切换目录的方法。</p>
<p>zsh自带一个命令可以查看最近访问过的目录，下面的命令会列出当前会话最近访问过的30个目录：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="bu">alias</span> ds=<span class="st">'dirs -v | head -n 30'</span>
$ <span class="ex">ds</span>
<span class="ex">0</span>	/current/dir
<span class="ex">1</span>	/path/to/dir/1
<span class="ex">2</span>	/path/to/dir/2
<span class="ex">3</span>	/path/to/dir/3</code></pre></div>
<p>执行 <code>\cd +1</code> 会进入1对应的目录，同理可将1改成其它数字，则进入该数字对应的目录。之所以用 <code>\cd</code> 是因为我系统上的cd是 <code>__enhancd::cd</code> 的别名，如果执行 <code>cd +1</code> 会有问题。</p>
<p>过去几年在用autojump，autojump会记录我访问过的目录，执行 <code>j foo</code> 会跳转到名字包含foo的目录。</p>
<p>最近才改用enhancd和fasd，enhancd可配置使用不同的交互式过滤器如上文提到的fzf、fzy、percol和peco等，用zplug安装比较方便，手动安装也是可以的。</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="fu">git</span> clone https://github.com/b4b4r07/enhancd
$ <span class="bu">source</span> /path/to/enhancd/init.sh</code></pre></div>
<p><img src="https://i.imgur.com/LlZpmtc.gif" /></p>
<p>fasd受autojump、z和v启发，跟踪访问过的文件和目录，并对这些文件和目录按访问频率和最近访问时间进行排序，可直接用Homebrew安装：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="ex">brew</span> install fasd</code></pre></div>
<p>我的prezto配置加载了fasd，不需要额外安装，并且我增加了fcd函数及其tab自动完成，可见<a href="https://github.com/jeoygin/prezto/blob/mine/modules/fasd/init.zsh" class="uri">https://github.com/jeoygin/prezto/blob/mine/modules/fasd/init.zsh</a>。</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="bu">alias</span> a=<span class="st">'fasd -a'</span>        # any
<span class="bu">alias</span> s=<span class="st">'fasd -si'</span>       # show / search / select
<span class="bu">alias</span> d=<span class="st">'fasd -d'</span>        # directory
<span class="bu">alias</span> f=<span class="st">'fasd -f'</span>        # file
<span class="bu">alias</span> sd=<span class="st">'fasd -sid'</span>     # interactive directory selection
<span class="bu">alias</span> sf=<span class="st">'fasd -sif'</span>     # interactive file selection
<span class="bu">alias</span> z=<span class="st">'fasd_cd -d'</span>     # cd, same functionality as j in autojump
<span class="bu">alias</span> zz=<span class="st">'fasd_cd -d -i'</span> <span class="co"># cd with interactive selection</span></code></pre></div>
<p><img src="https://i.imgur.com/Uf1vEd5.gif" /></p>
<p>Github仓库：</p>
<ul>
<li><a href="https://github.com/wting/autojump" class="uri">https://github.com/wting/autojump</a></li>
<li><a href="https://github.com/b4b4r07/enhancd" class="uri">https://github.com/b4b4r07/enhancd</a></li>
<li><a href="https://github.com/clvv/fasd" class="uri">https://github.com/clvv/fasd</a></li>
</ul>
<h2 id="数据处理">数据处理</h2>
<p>这部份的命令历史悠久，久经考验，如有兴趣，可求助man、tldr或Google。</p>
<ul>
<li>awk</li>
<li>sed</li>
<li>cut</li>
<li>join</li>
<li>paste</li>
<li>tr</li>
<li>sort</li>
<li>uniq</li>
<li>shuf</li>
<li>wc</li>
<li>tee</li>
<li>diff</li>
<li>tar</li>
<li>zless</li>
<li>zmore</li>
<li>zcat</li>
<li>zgrep</li>
<li>gpg: 数据加密，<a href="https://gpgtools.org/" class="uri">https://gpgtools.org/</a></li>
<li>pandoc: 数据格式转换，<a href="https://pandoc.org/" class="uri">https://pandoc.org/</a></li>
<li>macOS
<ul>
<li>pbcopy: 该命令的标准输入复制剪贴板</li>
<li>pbpaste: 输出剪贴板</li>
<li>open: 打开文件</li>
</ul></li>
</ul>
<h2 id="数据传输">数据传输</h2>
<ul>
<li>wget</li>
<li>curl</li>
<li>rsync: 本地或远程文件同步</li>
<li>netcat: 网络传输</li>
</ul>
<h2 id="录屏">录屏</h2>
<ul>
<li>ttygif: <a href="https://github.com/icholy/ttygif" class="uri">https://github.com/icholy/ttygif</a></li>
<li>ttystudio: <a href="https://github.com/chjj/ttystudio" class="uri">https://github.com/chjj/ttystudio</a></li>
<li>toughtty: <a href="https://github.com/zyrolasting/toughtty" class="uri">https://github.com/zyrolasting/toughtty</a></li>
</ul>
<p>本文的截屏是用toughtty录的。</p>
<h2 id="系统相关">系统相关</h2>
<ul>
<li>top: 显示进程信息</li>
<li>w: 我是谁？</li>
<li>id: 返回用户ID</li>
<li>last: 用户最近登录情况</li>
<li>time: 统计命令执行时间</li>
</ul>
<h2 id="参考列表">参考列表</h2>
<ul>
<li><a href="https://github.com/jlevy/the-art-of-command-line" class="uri">https://github.com/jlevy/the-art-of-command-line</a></li>
<li><a href="https://github.com/alebcay/awesome-shell" class="uri">https://github.com/alebcay/awesome-shell</a></li>
<li><a href="https://github.com/unixorn/awesome-zsh-plugins" class="uri">https://github.com/unixorn/awesome-zsh-plugins</a></li>
<li><a href="http://www.tldp.org/LDP/abs/html/" class="uri">http://www.tldp.org/LDP/abs/html/</a></li>
<li><a href="https://google.github.io/styleguide/shell.xml" class="uri">https://google.github.io/styleguide/shell.xml</a></li>
</ul>
<h2 id="p.s.">P.S.</h2>
<p>工欲善其事，必先利其器，工具是为解决问题服务，勿为了工具而使用工具。</p>
    </div>
</div>
]]></description>
    <pubDate>Sat, 20 Jan 2018 00:00:00 UT</pubDate>
    <guid>http://jeoygin.org/2018/01/20/customize-macOS-5/</guid>
    <dc:creator>Jeoygin Wang</dc:creator>
</item>
<item>
    <title>闲话macOS四：基本命令行</title>
    <link>http://jeoygin.org/2018/01/07/customize-macOS-4/</link>
    <description><![CDATA[<div id="primary">
    <div class="inside">
        <h1 class="title">闲话macOS四：基本命令行</h1>
        <div class="opacity08"><small>
                <i>January  7, 2018 / <a href="http://jeoygin.org/label/macos/">macOS</a>, <a href="http://jeoygin.org/label/customization/">customization</a>, <a href="http://jeoygin.org/label/tool/">tool</a>, <a href="http://jeoygin.org/label/shell/">shell</a></i>
        </small></div>
        <br>
        <h2 id="基本命令">基本命令</h2>
<ul>
<li>帮助
<ul>
<li>man
<ul>
<li>执行man ls可以查看ls命令的帮助文档</li>
</ul></li>
</ul></li>
<li>文件管理
<ul>
<li>列举目录内容
<ul>
<li>ls</li>
<li>ls -l：显示详细信息</li>
</ul></li>
<li>当前目录
<ul>
<li>pwd</li>
<li>pwdx: 进程的当前工作目录</li>
</ul></li>
<li>进入目录
<ul>
<li>cd
<ul>
<li>cd //Users/Jeoygin/Projects/</li>
</ul></li>
</ul></li>
<li>目录栈
<ul>
<li>dirs
<ul>
<li>dirs -v | head -n 16</li>
</ul></li>
</ul></li>
<li>查看文件内容
<ul>
<li>cat</li>
<li>tac</li>
<li>less</li>
<li>head
<ul>
<li>head -n 10</li>
<li>head -n -100</li>
</ul></li>
<li>tail
<ul>
<li>tail -n 10</li>
<li>tail -n +100</li>
</ul></li>
</ul></li>
<li>查看文件类型
<ul>
<li>file</li>
</ul></li>
<li>查看二进制文件中的字符串
<ul>
<li>strings</li>
</ul></li>
<li>列举打开文件
<ul>
<li>lsof
<ul>
<li>lsof -iTCP -sTCP:LISTEN -nP</li>
<li>lsof -i :$port -nP</li>
</ul></li>
</ul></li>
<li>链接
<ul>
<li>ln</li>
<li>ln -s: 创建软链接</li>
</ul></li>
<li>权限
<ul>
<li>chmod
<ul>
<li>chmod u+x /path/to/file</li>
</ul></li>
<li>chown
<ul>
<li>chown -R jeoygin:jeoygin /path/to/dir</li>
</ul></li>
</ul></li>
<li>磁盘使用情况
<ul>
<li>du -sh *</li>
</ul></li>
<li>文件系统
<ul>
<li>df
<ul>
<li>df -lh</li>
</ul></li>
<li>mount</li>
<li>fdisk</li>
<li>mkfs</li>
</ul></li>
</ul></li>
<li>打印到标准输出
<ul>
<li>echo
<ul>
<li>echo “Hello $USER”</li>
</ul></li>
</ul></li>
<li>输入/输出重定向与管道
<ul>
<li>&gt;: 将命令输出重定向，比如重定向到指定文件，会覆盖原文件内容
<ul>
<li>&gt;&gt;: 同&gt;，但不会覆盖原文件内容</li>
<li>ls /path/to/somewhere &gt; /path/to/outout 2&gt;&amp;1</li>
</ul></li>
<li>&lt;: 输入重定向，比如将指定文件作为命令的输入</li>
<li><code>|</code>: 管道，将上一条命令的输入作为下一条命令的输入，每条命令就像流水线上的工人一样只负责自己的职责</li>
</ul></li>
<li>进程管理
<ul>
<li>ps
<ul>
<li>ps -ef: 用标准的格式显示进程</li>
<li>ps aux: 用BSD的格式显示进程</li>
</ul></li>
</ul></li>
<li>文本搜索
<ul>
<li>grep
<ul>
<li>ps -ef | grep test</li>
</ul></li>
</ul></li>
<li>任务管理
<ul>
<li>&amp;: 后台执行</li>
<li>ctrl-z: 挂起当前进程</li>
<li>ctrl-c: 终止当前进程</li>
<li>jobs</li>
<li>fg: 将挂起的进程在前台继续执行</li>
<li>bg</li>
<li>kill</li>
</ul></li>
<li>网络管理
<ul>
<li>ifconfig</li>
<li>ip</li>
<li>netstat
<ul>
<li>netstat -ntlp # Linux</li>
<li>netstat -anp tcp | grep -i ‘listen’ #macOS</li>
</ul></li>
<li>dig</li>
<li>nslookup</li>
<li>traceroute</li>
</ul></li>
<li>其它
<ul>
<li>alias
<ul>
<li>alias ll=‘ls -latr’</li>
</ul></li>
<li>date</li>
<li>history</li>
<li>nohup</li>
<li>xargs: 参数列表</li>
</ul></li>
</ul>
<h2 id="日常使用">日常使用</h2>
<p>zsh和bash都支持emacs和vi模式，默认是emacs，可用以下命令更改：</p>
<ul>
<li><code>set -o emacs</code></li>
<li><code>set -o vi</code></li>
</ul>
<p>使用命令行时我个人倾向于使用emacs模式，常用的快捷键有：</p>
<ul>
<li>ctrl-r: 反向搜索命令历史，我的zsh配置支持用上下键来回查找历史，所以这个已经很少使用了</li>
<li>ctrl-w: 删除光标前一个词</li>
<li>ctrl-k: 删除光标后的内容</li>
<li>ctrl-u: 删除所有内容</li>
<li>ctrl-a: 移动光标到行首</li>
<li>ctrl-e: 移动光标到行末</li>
<li>ctrl-b: 光标向后移动一个字符</li>
<li>ctrl-f: 光标向前移动一个字符</li>
<li>ctrl-d: 删除光标后的一个字符</li>
<li>ctrl-n: 下一条命令</li>
<li>ctrl-p: 上一条命令</li>
<li>ctrl-q: 保存输入的内容，执行一条新命令</li>
<li>ctrl-l: 清除屏幕</li>
<li>ctrl-y: 粘贴</li>
<li>ctrl-_: 撤销</li>
<li>alt-.: 粘贴历史命令的最后一个参数</li>
<li>alt-&lt;: 第一条历史命令</li>
<li>alt-&gt;: 最后一条历史命令</li>
<li>alt-b: 光标向后移动一个词</li>
<li>alt-f: 光标向前移动一个词</li>
<li>alt-d: 删除光标后的一个词</li>
<li>alt-u: 大写</li>
<li>alt-l: 小写</li>
<li>alt-t: 调换词顺序</li>
</ul>
<p>上述快捷键是由readline提供，详情可参见https://linux.die.net/man/3/readline。</p>
<h2 id="环境变量">环境变量</h2>
<p>执行env命令可以查看当前shell的环境变量和命令别名，常用的环境变量有：</p>
<ul>
<li><code>$USER</code></li>
<li><code>$HOME</code></li>
<li><code>$SHELL</code></li>
<li><code>$LANG</code></li>
<li><code>$EDITOR</code></li>
<li><code>$LIBRARY_PATH</code></li>
<li><code>$LD_LIBRARY_PATH</code></li>
</ul>
<h2 id="推荐列表">推荐列表</h2>
<ul>
<li><a href="https://github.com/jlevy/the-art-of-command-line" class="uri">https://github.com/jlevy/the-art-of-command-line</a></li>
<li><a href="https://github.com/alebcay/awesome-shell" class="uri">https://github.com/alebcay/awesome-shell</a></li>
<li><a href="https://github.com/unixorn/awesome-zsh-plugins" class="uri">https://github.com/unixorn/awesome-zsh-plugins</a></li>
<li><a href="http://www.tldp.org/LDP/abs/html/" class="uri">http://www.tldp.org/LDP/abs/html/</a></li>
<li><a href="https://google.github.io/styleguide/shell.xml" class="uri">https://google.github.io/styleguide/shell.xml</a></li>
</ul>
<h2 id="p.s.">P.S.</h2>
<p>工欲善其事，必先利其器，工具是为解决问题服务，勿为了工具而使用工具。</p>
    </div>
</div>
]]></description>
    <pubDate>Sun, 07 Jan 2018 00:00:00 UT</pubDate>
    <guid>http://jeoygin.org/2018/01/07/customize-macOS-4/</guid>
    <dc:creator>Jeoygin Wang</dc:creator>
</item>
<item>
    <title>闲话macOS三：与系统深入接触之命令行</title>
    <link>http://jeoygin.org/2017/12/17/customize-macOS-3/</link>
    <description><![CDATA[<div id="primary">
    <div class="inside">
        <h1 class="title">闲话macOS三：与系统深入接触之命令行</h1>
        <div class="opacity08"><small>
                <i>December 17, 2017 / <a href="http://jeoygin.org/label/macos/">macOS</a>, <a href="http://jeoygin.org/label/customization/">customization</a>, <a href="http://jeoygin.org/label/tool/">tool</a>, <a href="http://jeoygin.org/label/shell/">shell</a>, <a href="http://jeoygin.org/label/zsh/">zsh</a>, <a href="http://jeoygin.org/label/iterm/">iTerm</a></i>
        </small></div>
        <br>
        <p>大一上《计算机原理》课程就学习了<a href="https://zh.wikipedia.org/wiki/%25E7%2594%25A8%25E6%2588%25B7%25E7%2595%258C%25E9%259D%25A2">用户接口</a>（User Interface，简称UI，亦称用户界面）是系统和用户之间进行交互和信息交换的媒介，它实现信息的内部形式与人类可以接受形式之间的转换。</p>
<p>目前我个人对用户接口按如下分类：</p>
<ul>
<li><a href="https://zh.wikipedia.org/wiki/%25E5%2591%25BD%25E4%25BB%25A4%25E8%25A1%258C%25E7%2595%258C%25E9%259D%25A2">命令行接口</a>（Command Line Interface，简称CLI）：是在图形用户界面得到普及之前使用最为广泛的用户界面，它通常不支持鼠标，用户通过键盘输入指令，计算机接收到指令后，予以执行。</li>
<li><a href="https://zh.wikipedia.org/wiki/%25E5%25BA%2594%25E7%2594%25A8%25E7%25A8%258B%25E5%25BA%258F%25E6%258E%25A5%25E5%258F%25A3">应用程序接口</a>（Application Programming Interface，简称API）：软件系统不同组成部分衔接的约定，是操作系统或软件系统提供给应用程序调用使用的代码。
<ul>
<li><a href="https://zh.wikipedia.org/wiki/Web%E6%9C%8D%E5%8A%A1">Web服务</a>（Web Service）
<ul>
<li><a href="https://zh.wikipedia.org/wiki/%E5%9F%BA%E7%A4%8E%E8%A8%AD%E6%96%BD%E5%8D%B3%E6%9C%8D%E5%8B%99">基础设施即服务</a>（Infrastructure as a Service，简称IAAS）</li>
<li><a href="https://zh.wikipedia.org/wiki/%E5%B9%B3%E5%8F%B0%E5%8D%B3%E6%9C%8D%E5%8A%A1">平台即服务</a>（Platform as a Service，简称PAAS）</li>
<li><a href="https://zh.wikipedia.org/wiki/%E8%BD%AF%E4%BB%B6%E5%8D%B3%E6%9C%8D%E5%8A%A1">软件即服务</a>（Software as a Service，简称SAAS）</li>
</ul></li>
</ul></li>
<li><a href="https://zh.wikipedia.org/wiki/%25E5%259B%25BE%25E5%25BD%25A2%25E7%2594%25A8%25E6%2588%25B7%25E7%2595%258C%25E9%259D%25A2">图形用户接口</a>（Graphical User Interface，简称GUI）：是指采用图形方式显示的计算机操作用户界面。与早期的命令行接口相比，图形用户接口对于用户来说更易于接受，但降低了灵活性。</li>
</ul>
<p>由于使用命令行接口需要记住不少命令，很多人会认为命令行接口没有图形用户接口操作方便。但在熟悉常用命令的前提下，使用命令行接口可以比图形用户接口更灵活和高效，同时也更节约系统资源。关于记忆命令，我的经验是先用起来再说，不断挖掘新需求和用法，用多了就记住，估计很少人把常用命令和用法记住了再开始用吧。有些命令过段时间不用就会生疏，多查查man、<a href="http://tldr.sh/">tldr</a>和google就好。</p>
<p>对于使用Linux的读者想必对命令行不会感到陌生，Linux操作系统的配置、软件安装、查看日志等操作若是不用命令行可能会感觉到别扭。我之前使用过的archlinux默认是没有安装桌面环境，用户按自己需要一步一步把桌面环境搭建起来。当然Windows也是支持命令行，犹记得在大一时，看一老师在Windows上娴熟地使用命令行，感觉就像是电影里的黑客，当时觉得很酷炫。大概是在大一的时候，当时加入的ACM兴趣小组与另一兴趣小组（机缘巧合，后来上研究生时与其中一位师兄同在一实验室，他教会了我很多使用Linux的经验）共用食堂二层创新基地的一房间，可能受他们影响，开始接触Linux（Fedora和Ubuntu），但仅限于在虚拟中使用，熟悉的命令也有限。研究生进入实验室后又接触了CentOS、openSUSE和debian等，慢慢地将debian作为主要操作系统。后来可能因为集成的桌面环境占用较多资源导致系统比较卡，开始物色一个轻量级的Linux发行版，很快就发现了archlinux，连续使用了多年直到两年前完全使用macOS。</p>
<p>说了那么多有点扯远了，习惯了使用命令行接口后可能会多一个看软件系统的视角，不过在入坑前还是要先想想学习命令行是否会对工作和学习有帮助，是否会提高效率，毕竟喜欢命令行的人不占多数。</p>
<h2 id="终端">终端</h2>
<p>macOS自带了终端应用Terminal，可用Alfred或Spotlight打开。</p>
<p><img src="https://i.imgur.com/6QnWhvI.png" style="width:100.0%" /></p>
<p>由于Terminal不能左右分屏，很早我就改用iTerm了。</p>
<p><img src="https://i.imgur.com/Bj0TQuo.png" style="width:100.0%" /></p>
<p>对于iTerm，我必须要做的一个设置是把Option键映射为Esc+，如果使用Terminal的话是Edit-&gt;Use Option as Meta Key，这个Meta键对于终端重度用户很重要。</p>
<p><img src="https://i.imgur.com/lAldaPc.png" style="width:100.0%" /></p>
<h2 id="shell">Shell</h2>
<p>搞定了终端，接下来要考虑是的使用什么Shell，Shell可以理解为一个脚本执行引擎，用户输入文本形式的命令，Shell负责解释并执行输入的命令。</p>
<p>目前使用比较多的Shell有：</p>
<ul>
<li>bash</li>
<li>zsh</li>
<li>fish</li>
<li>clink（Windows）</li>
</ul>
<p>可用以下命令查看你的系统有哪些shell：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="fu">cat</span> /etc/shells
<span class="ex">/bin/bash</span>
<span class="ex">/bin/csh</span>
<span class="ex">/bin/ksh</span>
<span class="ex">/bin/sh</span>
<span class="ex">/bin/tcsh</span>
<span class="ex">/bin/zsh</span></code></pre></div>
<p>我最早使用的是bash，也是最熟悉的，即便现在Shell是用zsh，但写脚本还是会用bash，使用bash执行脚本文件的方法是在脚本文件头部加上：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="co">#!/usr/bin/env bash</span></code></pre></div>
<p>多年前参考<a href="http://www.tldp.org/LDP/abs/html/">Advanced Bash-Scripting Guide</a>学习了bash脚本。</p>
<p>自从看了<a href="http://macshuo.com/?p=676">《终极 Shell》</a>一文，尝到zsh的甜头就果断改投zsh门下。设置当前用户的login shell为zsh：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">chsh</span> -s /bin/zsh</code></pre></div>
<p>zsh的强大之处在于配置，不过已经有人提供了支持插件的配置框架，我们直接使用就可以了。我最早使用的是<a href="https://github.com/robbyrussell/oh-my-zsh">oh-my-zsh</a>，配置简单，设置要使用的插件和主题就可以愉快玩耍了。那到底zsh相比bash的优势在哪呢？</p>
<ul>
<li>输入命令或前缀，用山下箭头翻阅命令历史</li>
<li>智能拼写纠错</li>
<li>补全：命令补全、命令参数补全、路径补全等</li>
<li>目录浏览和跳转：输入d，列出在当前会话访问过的目录列表，序号即可跳转到对应的目录</li>
<li>输入目录名即可跳转，不需输入cd命令，输入…会自动转成../..</li>
<li>可以通过设置别名，针对文件类型设置对应的打开程序，比如 ~alias -s tgz=‘tar -xvf’~</li>
<li>插件支持</li>
</ul>
<p>后来由于觉得oh-my-zsh有点重了，加载有点慢，于是改用了<a href="https://github.com/jeoygin/prezto">prezto</a>（链接是我目前的配置）。</p>
<p>oh-my-zsh和prezto对于插件管理做得不是特别好，于是就有了<a href="https://github.com/zplug/zplug">zplug</a>、<a href="https://github.com/tarjoilija/zgen">zgen</a>和<a href="https://github.com/zsh-users/antigen">antigen</a>这类插件管理器。为了减少加载时间，目前我用zplug来安装插件，但没用它加载插件，<a href="https://github.com/unixorn/awesome-zsh-plugins">awesome-zsh-plugins</a>这个列表汇总了一些好用常用的插件。</p>
<p>写了这么多，最后我想给没使用过zsh的读者推荐的却是<a href="https://fishshell.com/">fish</a>，开箱即用，自带tab自动完成和语法高亮，号称是一个智能并对用户友好的命令行Shell，你值得拥有。</p>
<h2 id="推荐列表">推荐列表</h2>
<p>关于常用命令和操作下篇再续，此处先献上资源。</p>
<ul>
<li><a href="https://github.com/jlevy/the-art-of-command-line" class="uri">https://github.com/jlevy/the-art-of-command-line</a></li>
<li><a href="https://github.com/alebcay/awesome-shell" class="uri">https://github.com/alebcay/awesome-shell</a></li>
<li><a href="https://github.com/unixorn/awesome-zsh-plugins" class="uri">https://github.com/unixorn/awesome-zsh-plugins</a></li>
<li><a href="http://www.tldp.org/LDP/abs/html/" class="uri">http://www.tldp.org/LDP/abs/html/</a></li>
<li><a href="https://google.github.io/styleguide/shell.xml" class="uri">https://google.github.io/styleguide/shell.xml</a></li>
</ul>
<h2 id="p.s.">P.S.</h2>
<p>工欲善其事，必先利其器，工具是为解决问题服务，勿为了工具而使用工具。</p>
    </div>
</div>
]]></description>
    <pubDate>Sun, 17 Dec 2017 00:00:00 UT</pubDate>
    <guid>http://jeoygin.org/2017/12/17/customize-macOS-3/</guid>
    <dc:creator>Jeoygin Wang</dc:creator>
</item>
<item>
    <title>闲话macOS二：窗口管理之Hammerspoon</title>
    <link>http://jeoygin.org/2017/12/10/customize-macOS-2/</link>
    <description><![CDATA[<div id="primary">
    <div class="inside">
        <h1 class="title">闲话macOS二：窗口管理之Hammerspoon</h1>
        <div class="opacity08"><small>
                <i>December 10, 2017 / <a href="http://jeoygin.org/label/macos/">macOS</a>, <a href="http://jeoygin.org/label/customization/">customization</a>, <a href="http://jeoygin.org/label/tool/">tool</a>, <a href="http://jeoygin.org/label/alfred/">alfred</a></i>
        </small></div>
        <br>
        <p>在使用Mac时，不知你是否有过这样的想法？</p>
<ul>
<li>让应用窗口占据半个屏幕，比如一半屏幕是浏览器，另一半屏幕是命令行终端，边看文档边部署服务</li>
<li>外接显示器时，让窗口在屏幕之间移动</li>
</ul>
<p>加入前东家猿辅导后，平时开发主要使用macOS，在这之前，工作和个人使用主要是用Arch Linux，使用的窗口管理器是<a href="https://wiki.archlinux.org/index.php/i3">i3</a>，它是一个平铺式窗口管理器。使用过iTerm的读者可能知道一个iTerm窗口可以开多个Tab，每个Tab可以水平或垂直切分成多个面板。类似地，i3使用Workspace（如同Desktop）来聚合窗口，每个Workspace可以通过水平或垂直切分成多个窗口。</p>
<p>将多个窗口平铺在一个屏幕上可以减少应用切换和增强多任务工作体验，我个人比较喜欢这种方式，将macOS作为主要操作系统之后，习惯性地去搜罗窗口管理应用。目前macOS上的窗口管理应用不少，参考<a href="https://github.com/iCHAIT/awesome-macOS">iCHAIT/awesome-macOS</a>和<a href="https://github.com/jaywcjlove/awesome-mac">jaywcjlove/awesome-mac</a>推荐一些：</p>
<ul>
<li><a href="http://ianyh.com/amethyst/">Amethyst</a>: 平铺式窗口管理</li>
<li><a href="https://www.boastr.net/bettersnaptool/">BetterSnapTool</a>: €3.49</li>
<li><a href="https://github.com/koekeishiya/chunkwm">chunkwm</a>: 平铺式窗口管理</li>
<li><a href="http://mizage.com/divvy/">Divvy</a>: $13.99</li>
<li><a href="http://www.hammerspoon.org/">Hammerspoon</a>: 强大的macOS自动化工具</li>
<li><a href="http://magnet.crowdcafe.com/">Magnet</a>: $0.99</li>
<li><a href="https://manytricks.com/moom/">Moom</a>: $10</li>
<li><a href="https://github.com/kasper/phoenix">Phoenix</a></li>
<li><a href="https://github.com/fikovnik/ShiftIt">ShiftIt</a></li>
<li><a href="https://github.com/jigish/slate">Slate</a>: 试图替换Divvy/SizeUp/ShiftIt，需要配置</li>
<li><a href="https://www.spectacleapp.com/">Spectacle</a></li>
<li><a href="https://cordlessdog.com/stay/">Stay</a>: $15</li>
<li><a href="http://www.irradiatedsoftware.com/sizeup/">SizeUp</a>: $12.99</li>
</ul>
<p>我曾经尝试过上面的列表的差不多一半应用，最后选择了Hammerspoon：一是因为我个人偏好高度可配置的应用，Hammerspoon配置是用Lua语言编写，有编程经验的读者学习Lua相信会很快，可参考<a href="https://learnxinyminutes.com/docs/lua/">Learn X in Y minutes</a> ；二是 Hammerspoon背后是Lua脚本引擎，可以做的事情远不止窗口管理。没有编程经验或不想折腾的读者也可以从上述列表找一个无需配置开箱即用的应用。</p>
<h2 id="安装与配置">安装与配置</h2>
<p>从 <a href="https://github.com/Hammerspoon/hammerspoon/releases/latest" class="uri">https://github.com/Hammerspoon/hammerspoon/releases/latest</a> 下载Hammerspoon-x.x.x.zip，解压缩后将Hammerspoon移动到Applications，安装就完成了。</p>
<p>因为Hammerspoon配置使用Lua语言来写，需要先安装Luz：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">brew</span> install lua</code></pre></div>
<p>我目前使用的配置可见<a href="https://github.com/jeoygin/awesome-hammerspoon">jeoygin/awesome-hammerspoon</a>，在<a href="https://github.com/ashfinal/awesome-hammerspoon">ashfinal/awesome-hammerspoon</a>的基础上做了如下修改：</p>
<ul>
<li>增加Main Mode，通过Main Mode进入其它Mode</li>
<li>增加切换到特定应用的快捷键</li>
<li>支持循环切换同个应用的不同窗口，比如打开了三个Chrome窗口，可以在这三个窗口循环切换</li>
</ul>
<p>执行以下命令下载配置：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">git</span> clone --depth 1 https://github.com/jeoygin/awesome-hammerspoon.git ~/.hammerspoon</code></pre></div>
<p>重新加载配置之后，在桌面上可以看到Hammerspoon显示的日历。</p>
<p><img src="https://i.imgur.com/05ZFlME.png" /></p>
<h2 id="快捷键">快捷键</h2>
<p>目前已支持以下的快捷键：</p>
<ul>
<li>⌘ +⌃ +⇧ +R: 重新加载Hammerspoon配置</li>
<li>⌘ +⌃ +⇧ +1: 将当前窗口移动到第一个显示器</li>
<li>⌘ +⌃ +⇧ +2: 将当前窗口移动到第二个显示器</li>
<li>⌘ +⌃ +⇧ +3: 将当前窗口移动到第三个显示器</li>
<li>⌘ +⌃ +⇧ +4: 将当前窗口移动到第四个显示器</li>
<li>⌘ +⌃ +⇧ +N: 将当前窗口移动到下一个显示器</li>
<li>⌘ +⌃ +⇧ +C: 将当前窗口置于屏幕中央</li>
<li>⌘ +⌃ +⇧ +M: 将当前窗口最大化</li>
<li>⌘ +⌃ +⇧ +F: 将当前窗口全屏化</li>
<li>⌘ +⌃ +⇧ +←: 将当前窗口移动到左半个屏幕</li>
<li>⌘ +⌃ +⇧ +→: 将当前窗口移动到右半个屏幕</li>
<li>⌘ +⌃ +⇧ +↑: 将当前窗口移动到上半个屏幕</li>
<li>⌘ +⌃ +⇧ +↓: 将当前窗口移动到下半个屏幕</li>
<li>⌘ +⌃ +c: 跳转到Google Chrome窗口</li>
<li>⌘ +⌃ +j: 跳转到IntelliJ IDEA窗口</li>
<li>⌘ +⌃ +m: 跳转到NeteaseMusic窗口</li>
<li>⌘ +⌃ +o: 跳转到Microsoft Outlook窗口</li>
<li>⌘ +⌃ +t: 跳转到iTerm2窗口</li>
<li>⌘ +⌃ +x: 跳转到WeChat窗口</li>
</ul>
<h2 id="模式切换">模式切换</h2>
<p>除了以上快捷键，还可以按 <code>⌘  + space</code> 唤出如下图所示的Main Mode来进行其它操作。</p>
<p><img src="https://i.imgur.com/F2yhAug.png" /></p>
<p>按A进入Application Mode：</p>
<p><img src="https://i.imgur.com/79WwHvd.png" /></p>
<p>按I进入Timer Mode：</p>
<p><img src="https://i.imgur.com/6cTSvrE.png" /></p>
<p>按R进入Resize Mode：</p>
<p><img src="https://i.imgur.com/9N2eYtJ.png" /></p>
<p>按S进入Cheatsheet Mode：</p>
<p><img src="https://i.imgur.com/r1oRDoU.png" /></p>
<p>按Tab显示窗口提示：</p>
<p><img src="https://i.imgur.com/Gcmi0Nf.png" /></p>
<h2 id="p.s.">P.S.</h2>
<p>工欲善其事，必先利其器，工具是为解决问题服务，勿为了工具而使用工具。</p>
    </div>
</div>
]]></description>
    <pubDate>Sun, 10 Dec 2017 00:00:00 UT</pubDate>
    <guid>http://jeoygin.org/2017/12/10/customize-macOS-2/</guid>
    <dc:creator>Jeoygin Wang</dc:creator>
</item>
<item>
    <title>申请Let's Encrypt HTTPS证书</title>
    <link>http://jeoygin.org/2017/12/03/letsencrypt-certificate/</link>
    <description><![CDATA[<div id="primary">
    <div class="inside">
        <h1 class="title">申请Let's Encrypt HTTPS证书</h1>
        <div class="opacity08"><small>
                <i>December  3, 2017 / <a href="http://jeoygin.org/label/https/">HTTPS</a></i>
        </small></div>
        <br>
        <p><a href="https://letsencrypt.org/">Let’s Encrypt</a>是一个免费、自动化和开放的权威机构，它是由非盈利组织<a href="https://letsencrypt.org/isrg/">Internet Security Research Group (ISRG，互联网安全研究小组)</a>提供的一个服务。为了创建一个更加安全和保护隐私的网络，它向人们免费提供HTTPS（SSL/TLS）所需要的数字证书。Let’s Encrypt受到了Mozilla、Chrome、Akamai和CISCO等的支持。</p>
<p>本文使用一个开源工具<a href="https://github.com/Neilpang/acme.sh">acme.sh</a>来申请证书，acme.sh是一个用Shell脚本编写的<a href="https://ietf-wg-acme.github.io/acme/">ACME</a>（Automatic Certificate Management Environment，自动化证书管理环境）协议客户端，Let’s Encrypt正是使用ACME协议进行证书签发。</p>
<h2 id="安装">安装</h2>
<p><strong>安装OpenSSL:</strong></p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">sudo</span> apt-get install openssl</code></pre></div>
<p><strong>安装acme.sh</strong></p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">curl</span> https://get.acme.sh <span class="kw">|</span> <span class="fu">sh</span></code></pre></div>
<h2 id="签发证书">签发证书</h2>
<p>Let’s Encrypt需要验证域名，因此需要先修改Nginx配置，增加中间的 <strong>location ^~ <em>.well-known/acme-challenge</em></strong> 部分。如果有多个域名的话，记得对每个域名都做修改。</p>
<pre><code>server {
    listen       80;
    server_name  jeoygin.org;

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/challenges/;
        try_files $uri =404;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}
</code></pre>
<p>重新加载Nginx配置，然后执行acme.sh签发证书：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">sudo</span> usermod -a -G www-data <span class="va">$USER</span>
<span class="fu">sudo</span> mkdir -m 774 /var/www/challenges
<span class="fu">sudo</span> chown www-data:www-data /var/www/challenges
<span class="fu">sudo</span> nginx -s reload

<span class="ex">~/.acme.sh/acme.sh</span> --issue -d jeoygin.org -d wiki.jeoygin.org \
  -d file.jeoygin.org -d img.jeoygin.org -w /var/www/challenges</code></pre></div>
<p>安装证书并重新加载Nginx配置：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">sudo</span> mkdir -m 774 /var/www/ssl
<span class="fu">sudo</span> chown -R www-data:www-data /var/www/ssl
<span class="ex">acme.sh</span> --install-cert -d jeoygin.org \
--key-file       /var/www/ssl/key.pem  \
--fullchain-file /var/www/ssl/cert.pem \
--reloadcmd     <span class="st">&quot;service nginx force-reload&quot;</span></code></pre></div>
<h2 id="配置nginx">配置Nginx</h2>
<p>增加Nginx SSL配置：</p>
<pre><code>server {
    listen       443 ssl;
    server_name  jeoygin.org;
    error_page 404  /404.html;

    ssl_certificate      /var/www/ssl/cert.pem;
    ssl_certificate_key  /var/www/ssl/key.pem;

    location / {
        root   /var/www/jeoygin.org/public_html/;
        index  index.html index.htm;
    }

    access_log /var/log/nginx/jeoygin.org.log;
}

server {
    listen       80;
    server_name  jeoygin.org;

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/challenges/;
        try_files $uri =404;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}
</code></pre>
<p>重新加载Nginx配置：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">sudo</span> nginx -s reload</code></pre></div>
    </div>
</div>
]]></description>
    <pubDate>Sun, 03 Dec 2017 00:00:00 UT</pubDate>
    <guid>http://jeoygin.org/2017/12/03/letsencrypt-certificate/</guid>
    <dc:creator>Jeoygin Wang</dc:creator>
</item>
<item>
    <title>闲话macOS一：搜索入口之Alfred</title>
    <link>http://jeoygin.org/2017/12/02/customize-macOS-1/</link>
    <description><![CDATA[<div id="primary">
    <div class="inside">
        <h1 class="title">闲话macOS一：搜索入口之Alfred</h1>
        <div class="opacity08"><small>
                <i>December  2, 2017 / <a href="http://jeoygin.org/label/macos/">macOS</a>, <a href="http://jeoygin.org/label/customization/">customization</a>, <a href="http://jeoygin.org/label/tool/">tool</a>, <a href="http://jeoygin.org/label/alfred/">alfred</a></i>
        </small></div>
        <br>
        <p>如果说只能推荐一个Mac应用的话，<a href="https://www.alfredapp.com/">Alfred</a>会是笔者的选择，它是笔者使用最频繁也是最喜欢的应用，相信大多用户使用后也可以提高效率、节省时间。</p>
<h2 id="alfred-vs.-spotlight">Alfred vs. Spotlight</h2>
<p>很多读者朋友可能会觉得Alfred的功能不就是应用启动和本地/web搜索，然后可能会问既然macOS已经有Spotlight了，为什么还要使用Alfred，那笔者就先来对比下这两者。Spotlight可以帮助我们快速搜索计算机上的应用和文件和显示互联网、iTunes、App Store等的搜索结果，在笔者看来，Spotlight的主要功能是搜索（应用启动也可以算是一种搜索）。</p>
<p>相信每位读者朋友都有自己喜欢的启动/切换应用方式，笔者在几年前使用Arch Linux的时候或更多年前使用Windows就习惯于使用Application Launcher来启动/切换应用，可以减少鼠标的操作，所以使用Mac的时候很自然就用上了Spotlight。但由于搜索来源较多，所以要等几秒Spotlight才会显示搜索结果（可能笔者的MacBook Pro比较老了，性能下降了），虽然切换应用不需要等，但笔者有点强迫症，很快就通过搜索引擎找到了拥有强大定制能力的Alfred，当时免费版已经能够满足最初的需求了。</p>
<p>PS: Spotlight在过去几年不断改进，变得更加好用了，虽然搜索响应慢，但在搜索结果中可以浏览结果条目，这是个不错的feature.</p>
<p><img src="https://i.imgur.com/Ca5vbUr.png" style="width:100.0%" /></p>
<p>从上图可看出，除了File Search和Web Search，Alfred还提供了其它的功能。为了提高效率，Alfred通过关键字、快捷键和文本扩展来定制对应的功能，避免执行不必要的操作增加响应时间。比如在唤出Alfred搜索框后，可以通过如下默认关键字进行文件搜索：</p>
<ul>
<li><strong>open</strong>: 打开文件</li>
<li><strong>find</strong>: 在Finder中显示文件</li>
<li><strong>in</strong>: 查找包含搜索词的文件</li>
<li><strong>tags</strong>: 查找加上给定tag的文件</li>
</ul>
<p><img src="https://i.imgur.com/TvybfUB.png" /></p>
<p>既然用Alfred相对更高效，那么可以关闭Spotlight吗？Alfred依赖Spotlight的索引信息，如果关闭Spotlight的索引，Alfred将不能搜索本地的文件，所以Alfred不能完全取代Spotlight。</p>
<h2 id="免费版-vs.-powerpack">免费版 vs. Powerpack</h2>
<p>Alfred免费版已经提供了不错的功能如文件搜索、Web搜索、计算器、词典和体统命令等，一般公司内部各种工具如wiki、问答或代码仓库等会提供搜索功能，找到对应的搜索URL并添加一个Alfred自定义搜索，就可以快速搜索，比如Google搜索的URL是 <code>http://www.google.com/search?q={query}</code>.</p>
<p>如果想解锁额外的功能，需要购买Powerpack许可证，其为用户提供了灵活强大的集成和定制能力，单用户的v3许可证是19英镑，按目前汇率算大致是170RMB，不便宜，可视经济情况决定购买，毕竟免费版也可以满足日常使用了。笔者在挖掘Powerpack的高度定制能力后，发现其物超所值（笔者偏爱可高度定制的工具），而且Alfred有很好的社区和很多强有力的workflow，如果没找到满足特定需求的workflow，创建一个新的workflow也不难。</p>
<p><img src="https://i.imgur.com/0Q20qtU.png" style="width:100.0%" /></p>
<p>上图是笔者最近一个月一台MacBook上Alfred的使用情况，Hotkeys使用频率最高，其次是Clipboard。Clipboard是一个好用的功能，可以自动保存复制的文本、图片或文件，方便从剪贴板历史搜索需要的内容。笔者设置在剪贴板历史的顶部显示“All Snippets”，可以粘贴一些常用的文本片段。</p>
<p><img src="https://i.imgur.com/6O09rs8.png" style="width:100.0%" /></p>
<h2 id="workflows">Workflows</h2>
<p>通过Alfred的Powerpack和workflow，用户能够扩展并以自己的方式完成事情。以workflow替代重复的任务，从而提高效率。普通用户可以从如下链接寻找想要的workflow：</p>
<ul>
<li><a href="https://www.alfredapp.com/workflows/" class="uri">https://www.alfredapp.com/workflows/</a></li>
<li><a href="http://www.packal.org/" class="uri">http://www.packal.org/</a></li>
<li><a href="https://github.com/zenorocha/alfred-workflows" class="uri">https://github.com/zenorocha/alfred-workflows</a></li>
<li><a href="https://github.com/derimagia/awesome-alfred-workflows" class="uri">https://github.com/derimagia/awesome-alfred-workflows</a></li>
<li><a href="https://github.com/willfarrell/alfred-workflows" class="uri">https://github.com/willfarrell/alfred-workflows</a></li>
<li><a href="https://github.com/learn-anything/alfred-workflows" class="uri">https://github.com/learn-anything/alfred-workflows</a></li>
<li><a href="https://www.alfredforum.com/" class="uri">https://www.alfredforum.com/</a></li>
</ul>
<p>所谓的workflow就是工作流，通过创建一个个动作并以有向无环图的形式组织起来，提供一个输入，Alfred会完成对应工作流上的所有动作。拥有编程能力的用户可以通过编写脚本来完成其中的某些动作，支持bash、zsh、php、ruby、python、perl和osascript等语言，通过Alfred作为入口，可以完成大部分事情。从<a href="https://medium.com/@NikitaVoloboev/writing-alfred-workflows-in-go-2a44f62dc432">Writing Alfred Workflows in Go</a>这篇文章可以看出用Go语言也是可以编写workflow的，以此类推，其它语言也是可以做到的。</p>
<p>为了方便切换浏览器tab，最近笔者安装了一个workflow <a href="https://github.com/stuartcryan/rapid-browser-tabs-for-alfred">rapid-browser-tabs-for-alfred</a>，优点是可以在多个浏览器之间切换tab，不足是响应没有浏览器内部安装的扩展程序切换顺畅。可见下图。</p>
<p><img src="https://i.imgur.com/XMQqxws.png" style="width:100.0%" /></p>
<p>也有workflow可以切换iTerm tab: <a href="https://github.com/isometry/alfred-tty">alfred-tty</a>。</p>
<p><a href="https://i.imgur.com/A9rrl36.png" class="uri">https://i.imgur.com/A9rrl36.png</a></p>
<h2 id="同步">同步</h2>
<p>激活Alfred Powerpack后可以使用同步功能，可以在多台Mac同步设置、主题、Workflows和Snippets等。</p>
<p>设置同步的步骤如下：</p>
<ul>
<li>打开Alfred Preferences并进入Advanced tab</li>
<li>在右下角可以看到Syncing设置，点击“Set sync folder…”</li>
<li>选择一个用于同步设置的目录（比如~/Dropbox/Alfred）并点击“Set folder and restart Alfred”</li>
<li>Alfred将会重启</li>
</ul>
<p><img src="https://i.imgur.com/FlCoK8E.png" /></p>
<p>除了Dropbox，其它网盘如iCloud、Google Drive或百度云盘也是可以用于同步的。 需要注意的是要先在主要的Mac上设置同步，待设置同步完成后，再在其它Mac上设置同步，因为其它Mac会放弃原先的设置。</p>
<h2 id="引用">引用</h2>
<ul>
<li><a href="https://www.alfredapp.com/">Alfred</a></li>
<li><a href="https://www.alfredapp.com/help/troubleshooting/indexing/spotlight/">Can Alfred work without Spotlight enabled?</a></li>
<li><a href="https://www.alfredapp.com/workflows/" class="uri">https://www.alfredapp.com/workflows/</a></li>
<li><a href="http://www.packal.org/" class="uri">http://www.packal.org/</a></li>
<li><a href="https://github.com/zenorocha/alfred-workflows" class="uri">https://github.com/zenorocha/alfred-workflows</a></li>
<li><a href="https://github.com/derimagia/awesome-alfred-workflows" class="uri">https://github.com/derimagia/awesome-alfred-workflows</a></li>
<li><a href="https://github.com/willfarrell/alfred-workflows" class="uri">https://github.com/willfarrell/alfred-workflows</a></li>
<li><a href="https://github.com/learn-anything/alfred-workflows" class="uri">https://github.com/learn-anything/alfred-workflows</a></li>
<li><a href="https://www.alfredforum.com/" class="uri">https://www.alfredforum.com/</a></li>
<li><a href="https://medium.com/@NikitaVoloboev/writing-alfred-workflows-in-go-2a44f62dc432" class="uri">https://medium.com/@NikitaVoloboev/writing-alfred-workflows-in-go-2a44f62dc432</a></li>
<li><a href="https://github.com/stuartcryan/rapid-browser-tabs-for-alfred" class="uri">https://github.com/stuartcryan/rapid-browser-tabs-for-alfred</a></li>
</ul>
<h2 id="p.s.">P.S.</h2>
<p>工欲善其事，必先利其器，工具是为解决问题、做好事情服务，勿为了工具而使用工具。</p>
    </div>
</div>
]]></description>
    <pubDate>Sat, 02 Dec 2017 00:00:00 UT</pubDate>
    <guid>http://jeoygin.org/2017/12/02/customize-macOS-1/</guid>
    <dc:creator>Jeoygin Wang</dc:creator>
</item>
<item>
    <title>闲话macOS零</title>
    <link>http://jeoygin.org/2017/11/19/customize-macOS-0/</link>
    <description><![CDATA[<div id="primary">
    <div class="inside">
        <h1 class="title">闲话macOS零</h1>
        <div class="opacity08"><small>
                <i>November 19, 2017 / <a href="http://jeoygin.org/label/macos/">macOS</a>, <a href="http://jeoygin.org/label/customization/">customization</a>, <a href="http://jeoygin.org/label/tool/">tool</a></i>
        </small></div>
        <br>
        <p>博客有将近五年停止更新了，只在<a href="http://wiki.jeoygin.org/">Wiki</a>记录些笔记，最近想为博客注入新的生命力，但一直也没想好要写点什么。工作后这几年陆陆续续在尝试一些工具，通过定制来满足笔者的需求以及简化和自动化工作流，想先写一个序列介绍笔者是如何通过组合各种APP和命令行工具《打造个性化的macOS》，也是对现状做个总结。虽然是针对macOS，但用到的有些工具是跨平台的，其它很多工具在其它操作系统（比如Linux和Windows）也可以找到对等物。两三年前笔者就想写一篇《打造个性化的ArchLinux》，但两年前换工作后渐渐发现用macOS可以少点折腾，于是就没怎么用Arch Linux了。</p>
<p>第一篇先来讲讲这篇文章是如何诞生，具体用到的工具后续文章再作详细介绍。</p>
<h2 id="使用hakyll生成博客">使用Hakyll生成博客</h2>
<p><a href="https://jaspervdj.be/hakyll/">Hakyll</a>是一个用于生成静态网站的Haskell库，与<a href="http://pandoc.org/">Pandoc</a>集成使其可支持markdown、TeX和Emacs <a href="http://orgmode.org/">org-mode</a>等多种格式。一年前想用org-mode格式来写博客，很幸运找到了Hakyll，也发现了支持org-mode格式的Wiki程序gitit。</p>
<p>最近发现一年前找的Hakyll博客模板<a href="https://github.com/dannysu/hakyll-blog">hakyll-blog</a>编译有问题，昨天花点时间更新了最新模板，并对必要的地方做了修改。为方便日后更新，在Dannysu的hakyll-blog本地git仓库上建立一个新的分支并提交所做的修改。</p>
<p>笔者博客的git仓库是<a href="https://github.com/jeoygin/hakyll-blog"><a href="https://github.com/jeoygin/hakyll-blog" class="uri">https://github.com/jeoygin/hakyll-blog</a></a>，进入hakyll-blog本地仓库后，生成博客只需要执行一条命令：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">make</span> build</code></pre></div>
<p>编写文章时可以启动本地服务器，有内容变更时会自动生成博客：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">make</span> monitor</code></pre></div>
<p>部署生成的博客到服务器也很简单：</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">make</span> deploy</code></pre></div>
<h2 id="emacs编写文章">Emacs编写文章</h2>
<p>用Emacs org-mode记笔记或写文章很方便，除了用Hakyll生成，当然也是可以用org-mode强大的导出功能，本文源码可见<a href="https://github.com/jeoygin/hakyll-blog/tree/master/posts/2017-11-19-customize-macOS-0.org">2017-11-19-customize-macOS-0.org</a>。</p>
<p>源码以文章的元信息开始，这部分是用<a href="https://github.com/jeoygin/oh-my-elephant/blob/master/snippets/org-mode/hakyll-page-header">YAS snippet</a>自动完成，输入 <code>\hph+TAB</code> 即可。而源码块是输入 <code>&lt;s+TAB</code> 自动完成，org-mode的Babel默认支持。</p>
<h2 id="传送门">传送门</h2>
<ul>
<li><a href="http://wiki.jeoygin.org/macOS">macOS wiki</a></li>
</ul>
<h2 id="p.s.">P.S.</h2>
<p>工欲善其事，必先利其器，工具是为解决问题、做好事情服务，勿为了工具而使用工具。</p>
    </div>
</div>
]]></description>
    <pubDate>Sun, 19 Nov 2017 00:00:00 UT</pubDate>
    <guid>http://jeoygin.org/2017/11/19/customize-macOS-0/</guid>
    <dc:creator>Jeoygin Wang</dc:creator>
</item>
<item>
    <title>2012年总结</title>
    <link>http://jeoygin.org/2013/01/28/farewell-to-2012/</link>
    <description><![CDATA[<div id="primary">
    <div class="inside">
        <h1 class="title">2012年总结</h1>
        <div class="opacity08"><small>
                <i>January 28, 2013 / <a href="http://jeoygin.org/label/2012/">2012</a>, <a href="http://jeoygin.org/label/%E6%80%BB%E7%BB%93/">总结</a>, <a href="http://jeoygin.org/label/%E6%89%BE%E5%B7%A5%E4%BD%9C/">找工作</a>, <a href="http://jeoygin.org/label/%E6%94%B9%E5%8F%98/">改变</a>, <a href="http://jeoygin.org/label/%E8%8B%B1%E8%AF%AD/">英语</a></i>
        </small></div>
        <br>
        <p>这几天年会、婚礼轮轴转，这会终于能闲下心来写点东西，总结一下过去一年的点滴！</p>
<p>此刻是2013-01-27 21：33，以我目前的写作水平，我不知道此文最后会是什么样子，只能先来头脑风暴一下2012的关键词。</p>
<p>学英语、找工作、改变、记录、忙里偷闲这几个词可以总结我的2012年。</p>
<!--more-->
<p><strong>学英语</strong></p>
<p>英语一直是我的硬伤，听说读写样样烂，尽管我认为去狂补也无济于事，但为了找工作，只能放手一搏，企求屌丝能够逆袭。</p>
<p>学习英语音标，背单词，背常用短语，学习语法，听VOA Special，做听写，写日记（这个后来实在写不下去了，因为每天的日记都千篇一律）。</p>
<p>背过几遍托福单词，由VOA Special过渡到VOA Standard，后来听老托福听力，慢慢有了点信心。</p>
<p>万事开头难，遇到不熟悉的事情，总会担心无法搞定，但我们只要克服心中的畏惧，使劲搞，可能就会离成功越来越近。</p>
<p>后来把国内的某个考试通过了，成绩尚可，但我还是觉得英语比较差，到了一个更高的瓶颈，而且发现我的中文也有同样的问题：写不通顺、说不流畅、读下句忘前句、听话只记当前句。</p>
<p>语言是我一个很头疼的问题，未来可能会给我带来不少麻烦，必须想办法去完善，书读得少、话说得少、少与人交流是导致这个问题的几个重要原因。</p>
<p>还是多看点书、多背点文章、学唱几首歌、多和人说话吧！</p>
<p><strong>找工作</strong></p>
<p>这是人生的几件大事之一，是2012年的头等大事，给予了足够的重视，却未做好充分的准备。</p>
<p>6月份才正式开始准备找工作，看书、复习算法，先后看了《深入理解计算机系统》、《编程之美》、《编程珠玑》、《程序员面试宝典》、《深入理解Java虚拟机》、《Cracking the Coding Interview》等书，复习了线性代数、概率与统计、组合数学等知识，陆陆续续也在网上看了一些面试题，从8月底开始面试，一直到11月底结束战斗。</p>
<p>先来说一些好的。首先，简历还算漂亮，之前玩过一些技术，也做过一些有趣的项目，还是有比较实在的内容。其次，大部分笔试做得还行，有几个笔试应该算是挺不错的。最后，很多公司前几轮的技术面试基本能通过，主要考查内容是写代码或问一些比较细节的技术问题。</p>
<p>不足的是中后期的面试几乎都挂在最后一轮，在谈人生谈理想中谈挂了，最后自己总结的一个原因是：害怕说话，面试前就觉得面试可能会不成功结果怎么可能理想。没有野心，没有魄力，没有信心，不知道最想做的事情是什么，不知道喜欢什么，对未来没做好规划，交流能力欠缺，不会表达自己……这些导致了一次次的面试失败。</p>
<p>周围的同学经过一些面试后总结出经验，一个个都练成了面霸，而我依然还是新手，跟面试官谈话容易找不到头绪，时不时还会紧张，特别是谈人生谈理想时，简直被同学们完爆好几条街。</p>
<p>众多公司的面试当中，Google给人的体验最好的，很遗憾的是在9月底时就和Google、Microsoft和Hulu这些公司说再见，以至于我后面失去了信心和斗志，我真得还需要去好好锤炼。</p>
<p>求职过程中的几多辛酸能有几人理解，现在差不多已成定局，虽然不是最期盼的，但也比较满意，应该是离下一步的目标最接近。这几个月中想明白了一些问题，这对个人的成长来说非常重要。</p>
<p>单就找工作历程就可以另开一篇文章来写了，这个有时间再来构思吧。</p>
<p><strong>改变</strong></p>
<p>有一天，上帝突然对我说：“你不能再做一个木讷呆板的码农，你要改变！”于是，我开始尝试改变自己。</p>
<p>其实，在很久很久以前，我曾以为只要技术做得足够好就行了，但现在才发现原来光有技术是不够的，身体状况、精神状态、交际能力等可能会阻碍我在技术领域走得更远。于是，我必须做出改变。</p>
<p>心想着要干牛逼的事情，但我自知不是一个牛逼的人，只是个听话的学生、孩子，而不是聪明的学生，对于给予的任务，会想尽办法做到最好，却很少去想为什么要做那样的事情、去想为什么要接受那样的任务、去想做那样的事情后对自己有何提高，一直在做很多各式各样的事情，很杂很泛，没有重心，没有积累，没有提高，而且过得比较累。有时眼高手低，不愿做一些不起眼的事情，有些事情不愿意做第二次，其实如果能把基本的事情做牛逼了也是一件了不起的事情，任何事情都能让一个人成长，只有自己看得不够远安于现状时才会原地踏步。因此，我不能什么都想做，否则我会一直是个半吊子，我必须找到一个喜欢做的事情，深入去学习去探索，以期成为某个方面的专家。</p>
<p>什么都能接受意味着什么都不想接受，要以挑剔的眼光看世界，能分清是非黑白，有喜好与厌恶，在尘世中保持一颗平凡而真诚的心。</p>
<p>多看书、多看电影，并在其中学习琢磨作者、导演、人物的思想、情绪以及感情等。</p>
<p>多说话，改变一贯沉默不语的风格，不过目前还未改变彻底，或许，我天生就是个观察者和行动者，话不多。</p>
<p>多与人交往，扩大交际圈子，通过交流来学习一些课本上没有东西，在生活中学习。</p>
<p>多运动，打羽毛球，游泳，健身，保持一个强健的体魄，才有精力学习与工作。羽毛球水平一般，游泳刚学会自由泳，动作不是很规范，游得很慢且比较吃力。</p>
<p>开始吃以前不吃的葱、姜、蒜、芹菜等。</p>
<p><strong>记录</strong></p>
<p>主要是记录了一年完整的简短日志和财政收支。</p>
<p>我也没想到我能完成上面的任务。但目前的日志还存在一些问题，比如信息不够详细：没有时间、地点、人物及重要事件。</p>
<p>在年初做的财政计划就是每月将收入的30％存起来，有几个月支出比较大，超出了收入，虽然整年支出比较多，最后算下来还是攒了一笔小钱。</p>
<p><strong>忙里偷闲</strong></p>
<p>忙学习、忙项目、忙找工作、忙毕设，但劳逸结合可能效率会更佳，特别是看到各种程序员猝死的消息，更不敢像以前那样拼命了，本来体质就没别人好，容易把命都拼没了，因此大胆做出了改变，每周抽出点时间看看电影或出去玩玩，积极参与各种活动。</p>
<p>春游、夏游、上海两日游、骑行、海边游泳等各种活动还不少，后来又萌发学习摄影的念头，要以摄影师的眼光看世界，记录生活的点滴，于是买了个单反，但现在手中利器还不太会使用，各种摄影技术还不知晓，路还很长，慢慢学习。</p>
<p>某天，好像发神经似的想学习笛子，于是就在京东买了一把G调竹笛和一本笛子教程，学习笛子的初衷是为了练气，因为平时说话老感觉气不顺，于是要练习呼吸，这个理由似乎有点无哩头。买完也没花太多时间去练，目前还不会。</p>
<p>现在又觉得我想做的事情太多了，需要砍掉一些，不能太贪心了，专心搞好一个就好了。</p>
<p>=================================================================</p>
<p>华丽的分界线下就要来看看去年所做的2012年计划的完成情况以及做2013年计划。</p>
<p>去年所做的新年计划如下：</p>
<ol style="list-style-type: decimal">
<li>工作：年后把一切杂事处理完，开始新的工作；</li>
<li>Java：继续学习，最好能脱离IDE；</li>
<li>找工作：可能去外企？互联网公司？一切皆是未知数，不想花太多时间在准备找工作上，找一个喜欢的、成长空间较大的职位就好；</li>
<li>英语：加强口语、写作，希望能达到与外国人简单交流、写paper的程度，如果能过六级或托福考试那更好；</li>
<li>Hadoop：学习MapReduce、熟悉外围系统、学习源码；</li>
<li>练说话之道：能清楚地表达思想，与人流畅沟通，变得自信；</li>
<li>读好书，2012年书单：http//book.douban.com/doulist/1432612/；</li>
<li>提高游泳、羽毛球技术；</li>
<li>去一个离北京远点的地方旅行；</li>
<li>了解中国IT行业及互联网的发展趋势，寻找适合自己的方向；</li>
<li>让自己更稳重、更有主见、胸襟更宽广。</li>
</ol>
<p>1、2、3、8、9基本完成。</p>
<p>4、5、6没达到理想程度。</p>
<p>书单中的深入理解计算机系统、C程序设计语言、设计模式、编程珠玑、重构、编程之美、程序员修炼之道、Effective Java中文版、厚黑学、怪诞心理学、如何阅读一本书、史蒂夫·乔布斯传、一系列英语相关书籍、学会提问：批判性思维指南看完，大概完成了50％。</p>
<p>10中目前还是没能找到适合自己的方向，有点迷茫，只知道自己喜欢干实事，想做一些跟数据相关的事情，在工作之余我得找一个方向来学习。我需要去了解自己认识自己，根据自己所擅长的事情来定目标，利用自己的天赋来达成目标。</p>
<p>2013年计划：</p>
<ol style="list-style-type: decimal">
<li>完成毕业设计，顺利毕业</li>
<li>按期入职，熟悉公司环境，完成研修期任务，顺利转正</li>
<li>学习一个新的技术</li>
<li>尝试混一些问答社区，像Stack Overflow、Quora、知乎等</li>
<li>学习数学，从小就喜欢数学，但上本科后竟给落下了，数学是个奇妙的东西</li>
<li>学习英语，在外企工作必须用英语交流，对以后的发展肯定也有好处，目前计划是：每天看和读一篇文章、每天听英语新闻、背一些美文、学唱一些英文歌、争取写日记</li>
<li>学习摄影，有空的话多出去拍些照片，在实践中学习</li>
<li>多看书，不过买了一堆纸质书又没看后，为了节能环保，我还是看电子书吧</li>
<li>Topcoder攒rating</li>
<li>运动健身，找羽毛球、游泳、仰卧起坐、卧推</li>
<li>了解一些新的方向，比如机器学习、机器视觉、数据挖掘、数据库等其中的一两个</li>
<li>学习经济学知识</li>
<li>在博客上多写一些有价值的文章</li>
<li>有一个计划，实现这个计划的时间可能会比较长，最后也可能没能实现，但不管怎样，努力去奋斗吧</li>
</ol>
<p>好了，就列这么多了，2013年估计也没太多的空闲可利用时间</p>
<p>当对社会和自己认识越清晰，就越觉得对有些事情自己无能为力…</p>
<p>谨以此文纪念我逝去的2012年！</p>
    </div>
</div>
]]></description>
    <pubDate>Mon, 28 Jan 2013 00:44:18 UT</pubDate>
    <guid>http://jeoygin.org/2013/01/28/farewell-to-2012/</guid>
    <dc:creator>Jeoygin Wang</dc:creator>
</item>
<item>
    <title>研究生第8季</title>
    <link>http://jeoygin.org/2012/12/31/eighth-season-of-graduate/</link>
    <description><![CDATA[<div id="primary">
    <div class="inside">
        <h1 class="title">研究生第8季</h1>
        <div class="opacity08"><small>
                <i>December 31, 2012 / <a href="http://jeoygin.org/label/%E5%AD%A6%E4%B9%A0/">学习</a>, <a href="http://jeoygin.org/label/%E5%B7%A5%E4%BD%9C/">工作</a>, <a href="http://jeoygin.org/label/%E7%94%9F%E6%B4%BB/">生活</a>, <a href="http://jeoygin.org/label/%E7%A0%94%E7%A9%B6%E7%94%9F/">研究生</a></i>
        </small></div>
        <br>
        <p>岁末年初，现正拖着2012的尾巴走向2013，在这跨年夜（我已记不起从什么时候起，12.29这一晚上多了点跨年的味道），身边几个同学在看跨年晚会，本也想凑个热闹，无奈我的Archlinux不给力呀，怎么整都播不了mms协议，只能另找乐子。本想写篇2012年的总结，但我习惯等回家时静下心来好好梳理一年发生的事，想起这么一篇小记被落下了，赶紧收拾心情，写下一点笨拙而苍白的文字。</p>
<!--more-->
<p><strong>小记：</strong></p>
<ul>
<li>准备某个英语考试，并以不错的成绩通过了，但我不能明说，了解我的亲们你们懂的，这是我多年心中的痛，英语依然还是我的痛处，写12年总结时会再细细道来。</li>
<li>参加阿里巴巴的一些活动，为找工作准备。</li>
<li>学习Linux驱动，不过项目上的事情进展不是很顺，后来就没有然后了。</li>
<li>参加几个活动，听师兄师姐介绍找工作经验，对后来找工作很有帮助，感谢你们无私地把一些宝贵经验倾囊相授。</li>
<li>崔皓组织北理工的同学去蟹岛游乐场，玩得很high，有些高空项目还有有点惧。见到了不少生人，但是我不是那种初次见面就能成为朋友的人，与很多人仅仅是一面之缘，在为人处事方面还是要多多改善。</li>
<li>看《深入理解计算机系统》、《编程之美》、《编程珠玑》、《Linux设备驱动》、《如何阅读一本书》、《Java程序员面试宝典》、《其实你不懂广东人》、《美语发音13秘诀》。</li>
<li>写中英文简历。</li>
<li>参加Hulu Open Day，被Hulu的高品质、快节奏工作所感染，希望能进入到这样的团队中，可惜自己还不够优秀。比较幸运，得到一个奖品——Hulu挎包。</li>
<li>搬回了青年公寓，离开科一招那一刻心中对科一招的不舍之心喷涌而出，平时看起来冷漠，关键时刻却几多伤感。</li>
<li>两个好友相继结婚，身边的人一个个开始组建家庭，不知什么时候我才能认真考虑这个问题。</li>
<li>回家，这几年很少回家，也很少往家里打电话，面对家人真不知说什么好，总不能说技术吧，在这方面，我真的是很不孝，趁现在回家还方便，有时间就多回家看看，探望日益年长的父母。</li>
<li>研读“结构之法算法之道”、“何海涛博客”等网站的算法题及文章</li>
<li>看公开课《Algorithms Part I》</li>
<li>实验室北戴河夏游，大一时去过一次，因此并不是很期待，不过比较喜欢参加集体活动，所以报名了，最后大家对这一次出游评价都不是太好。</li>
<li>开始找工作内推，阿里巴巴一二面，阿里巴巴所有也就两轮面试，这是最早拿到的offer。</li>
</ul>
<p>这一篇继续以流水帐的形式记录我在6、7、8月份的一些经历和体会，或许这会是记研究生系列的最后一篇，最近三个月发生的事我会在年终的总结中详细说，未来半年最重要的事情是毕设，比较单调。回头看这两年，能坚持每个季度写一篇小结对我个人来说已很不容易，虽然已在这个世界活了二十五年有余，但我写过的文字、说过的话少得可怜，看过的书也是屈指可数，导致在语言组织与人际交往等方面的能力很弱，我因此在求职过程中吃了很大的亏。于是，我现在会鼓励多去尝试一些新鲜的事物，不要因为不熟悉就退避三舍，不会可以学习，多接触一些人和事有利于自己的成长。要有眼光和远见，不要局限于当下所拥有和掌握的东西，要明确自己的目标，做好一切准备去争取自己想要的东西，持续学习，不断积累，厚积薄发。</p>
<p>完结。。。</p>
    </div>
</div>
]]></description>
    <pubDate>Mon, 31 Dec 2012 22:47:08 UT</pubDate>
    <guid>http://jeoygin.org/2012/12/31/eighth-season-of-graduate/</guid>
    <dc:creator>Jeoygin Wang</dc:creator>
</item>
<item>
    <title>Hadoop基准测试</title>
    <link>http://jeoygin.org/2012/12/14/hadoop-benchmarks/</link>
    <description><![CDATA[<div id="primary">
    <div class="inside">
        <h1 class="title">Hadoop基准测试</h1>
        <div class="opacity08"><small>
                <i>December 14, 2012 / <a href="http://jeoygin.org/label/benchmark/">benchmark</a>, <a href="http://jeoygin.org/label/example/">Example</a>, <a href="http://jeoygin.org/label/hadoop/">Hadoop</a>, <a href="http://jeoygin.org/label/hibench/">HiBench</a>, <a href="http://jeoygin.org/label/test/">Test</a></i>
        </small></div>
        <br>
        <p>测试对于验证系统的正确性、分析系统的性能来说非常重要，但往往容易被我们所忽视。为了能对系统有更全面的了解、能找到系统的瓶颈所在、能对系统性能做更好的改进，打算先从测试入手，学习Hadoop几种主要的测试手段。本文将分成两部分：第一部分记录如何使用Hadoop自带的测试工具进行测试；第二部分记录Intel开放的Hadoop Benchmark Suit: HiBench的安装及使用。</p>
<p><strong><big>1. Hadoop基准测试</big></strong></p>
<p>Hadoop自带了几个基准测试，被打包在几个jar包中，如hadoop-<em>test</em>.jar和hadoop-<em>examples</em>.jar，在Hadoop环境中可以很方便地运行测试。本文测试使用的Hadoop版本是cloudera的hadoop-0.20.2-cdh3u3。</p>
<p>在测试前，先设置好环境变量：</p>
<pre><code>$ export $HADOOP_HOME=/home/hadoop/hadoop
$ export $PATH=$PATH:$HADOOP_HOME/bin</code></pre>
<p>使用以下命令就可以调用jar包中的类：</p>
<pre><code>$ hadoop jar $HADOOP_HOME/xxx.jar</code></pre>
<!--more-->
<p><strong>(1). Hadoop Test</strong></p>
<p>当不带参数调用hadoop-test-0.20.2-cdh3u3.jar时，会列出所有的测试程序：</p>
<pre><code>$ hadoop jar $HADOOP_HOME/hadoop-test-0.20.2-cdh3u3.jar
An example program must be given as the first argument.
Valid program names are:
  DFSCIOTest: Distributed i/o benchmark of libhdfs.
  DistributedFSCheck: Distributed checkup of the file system consistency.
  MRReliabilityTest: A program that tests the reliability of the MR framework by injecting faults/failures
  TestDFSIO: Distributed i/o benchmark.
  dfsthroughput: measure hdfs throughput
  filebench: Benchmark SequenceFile(Input|Output)Format (block,record compressed and uncompressed), Text(Input|Output)Format (compressed and uncompressed)
  loadgen: Generic map/reduce load generator
  mapredtest: A map/reduce test check.
  minicluster: Single process HDFS and MR cluster.
  mrbench: A map/reduce benchmark that can create many small jobs
  nnbench: A benchmark that stresses the namenode.
  testarrayfile: A test for flat files of binary key/value pairs.
  testbigmapoutput: A map/reduce program that works on a very big non-splittable file and does identity map/reduce
  testfilesystem: A test for FileSystem read/write.
  testipc: A test for ipc.
  testmapredsort: A map/reduce program that validates the map-reduce framework's sort.
  testrpc: A test for rpc.
  testsequencefile: A test for flat files of binary key value pairs.
  testsequencefileinputformat: A test for sequence file input format.
  testsetfile: A test for flat files of binary key/value pairs.
  testtextinputformat: A test for text input format.
  threadedmapbench: A map/reduce benchmark that compares the performance of maps with multiple spills over maps with 1 spill</code></pre>
<p>这些程序从多个角度对Hadoop进行测试，TestDFSIO、mrbench和nnbench是三个广泛被使用的测试。</p>
<p><strong>TestDFSIO</strong></p>
<p>TestDFSIO用于测试HDFS的IO性能，使用一个MapReduce作业来并发地执行读写操作，每个map任务用于读或写每个文件，map的输出用于收集与处理文件相关的统计信息，reduce用于累积统计信息，并产生summary。TestDFSIO的用法如下：</p>
<pre><code>  TestDFSIO.0.0.6
  Usage: TestDFSIO [genericOptions] -read | -write | -append | -clean [-nrFiles N] [-fileSize Size[B|KB|MB|GB|TB]] [-resFile resultFileName] [-bufferSize Bytes] [-rootDir]</code></pre>
<p>以下的例子将往HDFS中写入10个1000MB的文件：</p>
<pre><code>$ hadoop jar $HADOOP_HOME/hadoop-test-0.20.2-cdh3u3.jar TestDFSIO \
  -write -nrFiles 10 -fileSize 1000</code></pre>
<p>结果将会写到一个本地文件TestDFSIO_results.log：</p>
<pre><code>----- TestDFSIO ----- : write
            Date &amp; time: Mon Dec 10 11:11:15 CST 2012
        Number of files: 10
 Total MBytes processed: 10000.0
      Throughput mb/sec: 3.5158047729862436
 Average IO rate mb/sec: 3.5290374755859375
 IO rate std deviation: 0.22884063705950305
     Test exec time sec: 316.615</code></pre>
<p>以下的例子将从HDFS中读取10个1000MB的文件：</p>
<pre><code>$ hadoop jar $HADOOP_HOME/hadoop-test-0.20.2-cdh3u3.jar TestDFSIO \
   -read -nrFiles 10 -fileSize 1000</code></pre>
<p>结果将会写到一个本地文件TestDFSIO_results.log：</p>
<pre><code>----- TestDFSIO ----- : read
            Date &amp; time: Mon Dec 10 11:21:17 CST 2012
        Number of files: 10
 Total MBytes processed: 10000.0
      Throughput mb/sec: 255.8002711482874
 Average IO rate mb/sec: 257.1685791015625
 IO rate std deviation: 19.514058659935184
     Test exec time sec: 18.459</code></pre>
<p>使用以下命令删除测试数据：</p>
<pre><code>$ hadoop jar $HADOOP_HOME/hadoop-test-0.20.2-cdh3u3.jar TestDFSIO -clean</code></pre>
<p><strong>nnbench</strong></p>
<p>nnbench用于测试NameNode的负载，它会生成很多与HDFS相关的请求，给NameNode施加较大的压力。这个测试能在HDFS上模拟创建、读取、重命名和删除文件等操作。nnbench的用法如下：</p>
<pre><code> NameNode Benchmark 0.4
 Usage: nnbench &lt;options&gt;
 Options:
      -operation &lt;Available operations are create_write open_read rename delete. This option is mandatory&gt;
       * NOTE: The open_read, rename and delete operations assume that the files they operate on, are already available. The create_write operation must be run before running the other operations.
      -maps &lt;number of maps. default is 1\. This is not mandatory&gt;
      -reduces &lt;number of reduces. default is 1\. This is not mandatory&gt;
      -startTime &lt;time to start, given in seconds from the epoch. Make sure this is far enough into the future, so all maps (operations) will start at the same time&gt;. default is launch time + 2 mins. This is not mandatory
      -blockSize &lt;Block size in bytes. default is 1\. This is not mandatory&gt;
      -bytesToWrite &lt;Bytes to write. default is 0\. This is not mandatory&gt;
      -bytesPerChecksum &lt;Bytes per checksum for the files. default is 1\. This is not mandatory&gt;
      -numberOfFiles &lt;number of files to create. default is 1\. This is not mandatory&gt;
      -replicationFactorPerFile &lt;Replication factor for the files. default is 1\. This is not mandatory&gt;
      -baseDir &lt;base DFS path. default is /becnhmarks/NNBench. This is not mandatory&gt;
      -readFileAfterOpen &lt;true or false. if true, it reads the file and reports the average time to read. This is valid with the open_read operation. default is false. This is not mandatory&gt;
      -help: Display the help statement</code></pre>
<p>以下例子使用12个mapper和6个reducer来创建1000个文件：</p>
<pre><code> $ hadoop jar $HADOOP_HOME/hadoop-test-0.20.2-cdh3u3.jar nnbench \
     -operation create_write -maps 12 -reduces 6 -blockSize 1 \
     -bytesToWrite 0 -numberOfFiles 1000 -replicationFactorPerFile 3 \
     -readFileAfterOpen true -baseDir /benchmarks/NNBench-`hostname -s`</code></pre>
<p><strong>mrbench</strong></p>
<p>mrbench会多次重复执行一个小作业，用于检查在机群上小作业的运行是否可重复以及运行是否高效。mrbench的用法如下：</p>
<pre><code> MRBenchmark.0.0.2
 Usage: mrbench [-baseDir &lt;base DFS path for output/input, default is /benchmarks/MRBench&gt;] [-jar &lt;local path to job jar file containing Mapper and Reducer implementations, default is current jar file&gt;] [-numRuns &lt;number of times to run the job, default is 1&gt;] [-maps &lt;number of maps for each run, default is 2&gt;] [-reduces &lt;number of reduces for each run, default is 1&gt;] [-inputLines &lt;number of input lines to generate, default is 1&gt;] [-inputType &lt;type of input to generate, one of ascending (default), descending, random&gt;] [-verbose]</code></pre>
<p>以下例子会运行一个小作业50次：</p>
<pre><code>$ hadoop jar $HADOOP_HOME/hadoop-test-0.20.2-cdh3u3.jar mrbench -numRuns 50</code></pre>
<p>运行结果如下所示：</p>
<pre><code> DataLines     Maps     Reduces     AvgTime (milliseconds)
 1          2     1     14237</code></pre>
<p>以上结果表示平均作业完成时间是14秒。</p>
<p><strong>(2). Hadoop Examples</strong></p>
<p>除了上文提到的测试，Hadoop还自带了一些例子，比如WordCount和TeraSort，这些例子在hadoop-examples-0.20.2-cdh3u3.jar中。执行以下命令会列出所有的示例程序：</p>
<pre><code> $ hadoop jar $HADOOP_HOME/hadoop-examples-0.20.2-cdh3u3.jar
 An example program must be given as the first argument.
 Valid program names are:
   aggregatewordcount: An Aggregate based map/reduce program that counts the words in the input files.
   aggregatewordhist: An Aggregate based map/reduce program that computes the histogram of the words in the input files.
   dbcount: An example job that count the pageview counts from a database.
   grep: A map/reduce program that counts the matches of a regex in the input.
   join: A job that effects a join over sorted, equally partitioned datasets
   multifilewc: A job that counts words from several files.
   pentomino: A map/reduce tile laying program to find solutions to pentomino problems.
   pi: A map/reduce program that estimates Pi using monte-carlo method.
   randomtextwriter: A map/reduce program that writes 10GB of random textual data per node.
   randomwriter: A map/reduce program that writes 10GB of random data per node.
   secondarysort: An example defining a secondary sort to the reduce.
   sleep: A job that sleeps at each map and reduce task.
   sort: A map/reduce program that sorts the data written by the random writer.
   sudoku: A sudoku solver.
   teragen: Generate data for the terasort
   terasort: Run the terasort
   teravalidate: Checking results of terasort
   wordcount: A map/reduce program that counts the words in the input files.</code></pre>
<p>WordCount在 <a href="2012/02/running-hadoop-on-centos-single-node-cluster.html">Running Hadoop On CentOS (Single-Node Cluster)</a> 一文中已有介绍，这里就不再赘述。</p>
<p><strong>TeraSort</strong></p>
<p>一个完整的TeraSort测试需要按以下三步执行：</p>
<ol style="list-style-type: decimal">
<li>用TeraGen生成随机数据</li>
<li>对输入数据运行TeraSort</li>
<li>用TeraValidate验证排好序的输出数据</li>
</ol>
<p>并不需要在每次测试时都生成输入数据，生成一次数据之后，每次测试可以跳过第一步。</p>
<p>TeraGen的用法如下：</p>
<pre><code>$ hadoop jar hadoop-*examples*.jar teragen &lt;number of 100-byte rows&gt; &lt;output dir&gt;</code></pre>
<p>以下命令运行TeraGen生成1GB的输入数据，并输出到目录/examples/terasort-input：</p>
<pre><code>$ hadoop jar $HADOOP_HOME/hadoop-examples-0.20.2-cdh3u3.jar teragen \
    10000000 /examples/terasort-input</code></pre>
<p>TeraGen产生的数据每行的格式如下：</p>
<pre><code>&lt;10 bytes key&gt;&lt;10 bytes rowid&gt;&lt;78 bytes filler&gt;\r\n</code></pre>
<p>其中：</p>
<ol style="list-style-type: decimal">
<li>key是一些随机字符，每个字符的ASCII码取值范围为[32, 126]</li>
<li>rowid是一个整数，右对齐</li>
<li>filler由7组字符组成，每组有10个字符（最后一组8个），字符从’A’到’Z’依次取值</li>
</ol>
<p>以下命令运行TeraSort对数据进行排序，并将结果输出到目录/examples/terasort-output：</p>
<pre><code>$ hadoop jar $HADOOP_HOME/hadoop-examples-0.20.2-cdh3u3.jar terasort \
   /examples/terasort-input /examples/terasort-output</code></pre>
<p>以下命令运行TeraValidate来验证TeraSort输出的数据是否有序，如果检测到问题，将乱序的key输出到目录/examples/terasort-validate</p>
<pre><code>$ hadoop jar $HADOOP_HOME/hadoop-examples-0.20.2-cdh3u3.jar teravalidate \
   /examples/terasort-output /examples/terasort-validate</code></pre>
<p><strong>(3). Hadoop Gridmix2</strong></p>
<p>Gridmix是Hadoop自带的基准测试程序，是对其它几个基准测试程序的进一步封装，包括产生数据、提交作业、统计完成时间等功能模块。Gridmix自带了各种类型的作业，分别为streamSort、javaSort、combiner、monsterQuery、webdataScan和webdataSort。</p>
<p><strong>编译</strong></p>
<pre><code>$ cd  $HADOOP_HOME/src/benchmarks/gridmix2
$ ant
$ cp build/gridmix.jar .</code></pre>
<p><strong>修改环境变量</strong></p>
<p>修改gridmix-env-2文件：</p>
<pre><code>export HADOOP_INSTALL_HOME=/home/jeoygin
export HADOOP_VERSION=hadoop-0.20.2-cdh3u3
export HADOOP_HOME=${HADOOP_INSTALL_HOME}/${HADOOP_VERSION}
export HADOOP_CONF_DIR=${HADOOP_HOME}/conf
export USE_REAL_DATASET=

export APP_JAR=${HADOOP_HOME}/hadoop-test-0.20.2-cdh3u3.jar
export EXAMPLE_JAR=${HADOOP_HOME}/hadoop-examples-0.20.2-cdh3u3.jar
export STREAMING_JAR=${HADOOP_HOME}/contrib/streaming/hadoop-streaming-0.20.2-cdh3u3.jar</code></pre>
<p>如果USE_REAL_DATASET的值为TRUE的话，将使用500GB压缩数据（等价于2TB非压缩数据），如果留空将使用500MB压缩数据（等价于2GB非压缩数据）。</p>
<p><strong>修改配置信息</strong></p>
<p>配置信息在gridmix_config.xml文件中。gridmix中，每种作业有大中小三种类型：小作业只有3个输入文件（即3个map）；中作业的输入文件是与正则表达式{part-000<em>0,part-000</em>1,part-000*2}匹配的文件；大作业会处理处有数据。</p>
<p><strong>产生数据</strong></p>
<pre><code>$ chmod +x generateGridmix2data.sh
$ ./generateGridmix2data.sh</code></pre>
<p>generateGridmix2data.sh脚本会运行一个作业，在HDFS的目录/gridmix/data中产生输入数据。</p>
<p><strong>运行</strong></p>
<pre><code>$ chmod +x rungridmix_2
$ ./rungridmix_2</code></pre>
<p>运行后，会创建_start.out文件来记录开始时间，结束后，创建_end.out文件来记录完成时间。</p>
<p><strong>(4). 查看任务统计信息</strong></p>
<p>Hadoop提供非常方便的方式来获取一个任务的统计信息，使用以下命令即可作到：</p>
<pre><code>$ hadoop job -history all &lt;job output directory&gt;</code></pre>
<p>这个命令会分析任务的两个历史文件（这两个文件存储在&lt;job output directory&gt;/_logs/history目录中）并计算任务的统计信息。</p>
<p><strong><big>2. HiBench</big></strong></p>
<p>HiBench是Intel开放的一个Hadoop Benchmark Suit，包含9个典型的Hadoop负载（Micro benchmarks、HDFS benchmarks、web search benchmarks、machine learning benchmarks和data analytics benchmarks），主页是：** https://github.com/intel-hadoop/hibench **。</p>
<p>HiBench为大多数负载提供是否启用压缩的选项，默认的compression codec是zlib。</p>
<p><strong>Micro Benchmarks:</strong></p>
<ul>
<li>Sort (sort)：使用Hadoop RandomTextWriter生成数据，并对数据进行排序</li>
<li>WordCount (wordcount)：统计输入数据中每个单词的出现次数，输入数据使用Hadoop RandomTextWriter生成</li>
<li>TeraSort (terasort)：这是由微软的数据库大牛Jim Gray（2007年失踪）创建的标准benchmark，输入数据由Hadoop TeraGen产生</li>
</ul>
<p><strong>HDFS Benchmarks:</strong></p>
<ul>
<li>增强的DFSIO (dfsioe)：通过产生大量同时执行读写请求的任务来测试Hadoop机群的HDFS吞吐量</li>
</ul>
<p><strong>Web Search Benchmarks:</strong></p>
<ul>
<li>Nutch indexing (nutchindexing)：大规模搜索引擎索引是MapReduce的一个重要应用，这个负载测试Nutch（Apache的一个开源搜索引擎）的索引子系统，使用自动生成的Web数据，Web数据中的链接和单词符合Zipfian分布</li>
<li>PageRank (pagerank)：这个负载包含一种在Hadoop上的PageRank算法实现，使用自动生成的Web数据，Web数据中的链接符合Zipfian分布</li>
</ul>
<p><strong>Machine Learning Benchmarks:</strong></p>
<ul>
<li>Mahout Bayesian classification (bayes)：大规模机器学习也是MapReduce的一个重要应用，这个负载测试Mahout 0.7（Apache的一个开源机器学习库）中的Naive Bayesian训练器，输入数据是自动生成的文档，文档中的单词符合Zipfian分布</li>
<li>Mahout K-means clustering (kmeans)：这个负载测试Mahout 0.7中的K-means聚类算法，输入数据集由基于均匀分布和高斯分布的GenKMeansDataset产生</li>
</ul>
<p><strong>Data Analytics Benchmarks:</strong></p>
<ul>
<li>Hive Query Benchmarks (hivebench)：这个负载的开发基于SIGMOD 09的一篇论文“A Comparison of Approaches to Large-Scale Data Analysis”和HIVE-396，包含执行典型OLAP查询的Hive查询（Aggregation and Join），使用自动生成的Web数据，Web数据中的链接符合Zipfian分布</li>
</ul>
<p>下文将${HIBENCH_HOME}定义为HiBench的解压缩目录。</p>
<p><strong>(1). 安装与配置</strong></p>
<p><strong>建立环境：</strong></p>
<ul>
<li>HiBench-2.2：从https://github.com/intel-hadoop/HiBench/zipball/HiBench-2.2下载</li>
<li>Hadoop：在运行任何负载之前，请确保Hadoop环境能正常运行，所有负载在Cloudera Distribution of Hadoop 3 update 4 (cdh3u4)和Hadoop 1.0.3上测试通过</li>
<li>Hive：如果要测试hivebench，请确保已正确建立了Hive环境</li>
</ul>
<p><strong>配置所有负载：</strong></p>
<p>需要在${HIBENCH_HOME}/bin/hibench-config.sh文件中设置一些全局的环境变量。</p>
<pre><code>$ unzip HiBench-2.2.zip
$ cd HiBench-2.2
$ vim bin/hibench-config.sh

HADOOP_HOME      &lt;The Hadoop installation location&gt;
HADOOP_CONF_DIR  &lt;The hadoop configuration DIR, default is $HADOOP_HOME/conf&gt;
COMPRESS_GLOBAL  &lt;Whether to enable the in/out compression for all workloads, 0 is disable, 1 is enable&gt;
COMPRESS_CODEC_GLOBAL  &lt;The default codec used for in/out data compression&gt;</code></pre>
<p><strong>配置单个负载：</strong></p>
<p>在每个负载目录下，可以修改conf/configure.sh这个文件，设置负载运行的参数。</p>
<p><strong>同步每个节点的时间</strong></p>
<p><strong>(2). 运行</strong></p>
<p><strong>同时运行几个负载：</strong></p>
<ol style="list-style-type: decimal">
<li>修改<strong>${HIBENCH_HOME}/conf/benchmarks.lst</strong>文件，该文件定义了将要运行的负载，每行指定一个负载，在任意一行前可以使用#跳过该行</li>
<li>运行<strong>${HIBENCH_HOME}/bin/run-all.sh</strong>脚本</li>
</ol>
<p><strong>单独运行每个负载：</strong></p>
<p>可以单独运行每个负载，通常，在每个负载目录下有三个不同的文件：</p>
<pre><code>conf/configure.sh   包含所有参数的配置文件，可以设置数据大小及测试选项等
bin/prepare*.sh   生成或拷贝作业输入数据到HDFS
bin/run*.sh       运行benchmark</code></pre>
<ol style="list-style-type: decimal">
<li>配置benchmark：如果需要，可以修改configure.sh文件来设置自己想要的参数</li>
<li>准备数据：运行bin/prepare.sh脚本为benchmark准备输入数据</li>
<li>运行benchmark：运行bin/run*.sh脚本来运行对应的benchmark</li>
</ol>
<p><strong>(3). 小结</strong></p>
<p>HiBench覆盖了一些广被使用的Hadoop Benchmark，如果看过该项目的源码，会发现该项目很精悍，代码不多，通过一些脚本使每个benchmark的配置、准备和运行变得规范化，用起来十分方便。</p>
<p><strong><big>3. 参考资料</big></strong></p>
<ol style="list-style-type: decimal">
<li><a href="http://www.michael-noll.com/blog/2011/04/09/benchmarking-and-stress-testing-an-hadoop-cluster-with-terasort-testdfsio-nnbench-mrbench">Benchmarking and Stress Testing an Hadoop Cluster with TeraSort, TestDFSIO &amp; Co.</a></li>
<li><a href="http://www.michael-noll.com/blog/2011/04/09/benchmarking-and-stress-testing-an-hadoop-cluster-with-terasort-testdfsio-nnbench-mrbench">Hadoop Gridmix基准测试</a></li>
<li><a href="https://github.com/intel-hadoop/HiBench">HiBench</a></li>
</ol>
    </div>
</div>
]]></description>
    <pubDate>Fri, 14 Dec 2012 18:29:03 UT</pubDate>
    <guid>http://jeoygin.org/2012/12/14/hadoop-benchmarks/</guid>
    <dc:creator>Jeoygin Wang</dc:creator>
</item>

    </channel>
</rss>
