<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>马楠的博客</title>
    <description>马楠的博客——发出声音就是寻找自我的开始。</description>
    <link>http://manan.org/</link>
    <atom:link href="http://manan.org/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Sun, 20 Jul 2025 12:03:45 +0000</pubDate>
    <lastBuildDate>Sun, 20 Jul 2025 12:03:45 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>读书笔记：《智能时代》和《硅谷之谜》</title>
        <description>&lt;p&gt;
很长时间没买纸质书了，最近对人工智能的关注开始增多，就读了吴军博士的《智能时代》和《硅谷之谜》，简单记录下感受。
&lt;/p&gt;

&lt;div id=&quot;outline-container-sec-1&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;sec-1&quot;&gt;《智能时代》&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-1&quot;&gt;
&lt;p&gt;
《智能时代》从工业革命、产业变迁的高度描述了正在到来的大数据、机器智能时代
。
&lt;/p&gt;

&lt;p&gt;
印象深刻的几点：
&lt;/p&gt;

&lt;ol class=&quot;org-ol&quot;&gt;
&lt;li&gt;数据的重要性

&lt;p&gt;
《万历十五年》中的一个重要观点是，明代的中国不能实现数目字管理，整个国家的治理混乱。而智能时代正好是这种情况的反面：科技、经济、社会治理的各项活动产生数据，从数据中抽象出信息和知识。
&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;智能时代蕴含着机械思维向大数据思维的转变

&lt;p&gt;
随着系统变得复杂，因果性越来越难以寻找，而数据为发现相关性提供了途径。人从利用因果性变为利用相关性，尽管相关性有时难以解释，但对解决许多问题是有效的。
&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;智能时代对社会和产业的变革性影响。

&lt;p&gt;
医疗、制药、法律、新闻等行业，都会被智能时代的先进技术改变。前一段时间特斯拉放出了最新的无人驾驶效果视频，令人惊叹：轿车自动行驶至目的地后，「驾驶员」下车离去，车辆自动寻找停车位并停放好自己。不需要太大胆的预测也能想到，5到10年内，人类驾驶员的作用将会逐渐淡化。
&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;负面影响

&lt;p&gt;
科技是一把双刃剑。智能时代和人类历次工业变革一样，也会给社会带来阵痛。比如，人工智能带来的自动化水平提高将取代许多人的工作，这样就业问题如何解决呢？供给侧改革后能源行业的工人还可以改行开专车，而自动驾驶成熟后，他们连这样的去处也少了一个。
&lt;/p&gt;

&lt;p&gt;
反应快、运气好的人还可以努力做下个时代前2%的人，但那些失落者是否会被时代抛弃？如果真的出现大量失业，或者造成社会鸿沟加剧，社会能否消化造成的影响？科技水平的提高，也应该伴随着人文水平、道德水平的提高。这些问题，需要未雨绸缪地做准备。
&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;解决问题的小例子

&lt;p&gt;
吴军博士提到了在谷歌做搜索引擎自动回答问题的工程方法，看似复杂的智能问题，分步骤用数据的方式解决，有一些启发性。如果有些智能问题难以解决，先用不那么高大上的方法做一个方案出来，也可以解决一定比例的问题，不用憋在原地寻找完备性。
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-sec-2&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;sec-2&quot;&gt;《硅谷之谜》&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-2&quot;&gt;
&lt;p&gt;
读过《浪潮之巅》的读者对这本书的话题不会陌生，相比前者，本书在理论上做了更多的升华总结，特别是从文化和思想层面解读了硅谷的独特之处。看不到硅谷的这一层先进之处，再造硅谷的尝试也许只能是『学我者病』。
&lt;/p&gt;

&lt;p&gt;
全书的逻辑结构很清晰：
&lt;/p&gt;
&lt;pre class=&quot;example&quot;&gt;
硅谷有多牛-&amp;gt;
其他人是怎么分析硅谷牛的原因的-&amp;gt;
硅谷历史回顾-&amp;gt;
指出硅谷的独特之处-&amp;gt;
升华到科学思想层面，对比机械和信息时代的不同。
&lt;/pre&gt;

&lt;p&gt;
务虚的思考表面上离实际工作有距离，其实不然。新的思想方式、企业制度正是生产关系对生产力的适应。参照书中的理论和现实经验，IT从业者至少可以试着判断什么样的公司（团队）是靠谱的，以及如何管理团队，如何合作。
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>
        <pubDate>Sat, 05 Nov 2016 16:00:00 +0000</pubDate>
        <link>http://manan.org/2016/11/book-review-smart-era</link>
        <guid isPermaLink="true">http://manan.org/2016/11/book-review-smart-era</guid>
        
        
      </item>
    
      <item>
        <title>一键登录 vpn</title>
        <description>&lt;p&gt;
公司的 VPN 采用了固定密码加 Google Authenticator 随机密码的两步验证方式，每次在家办公时手动输入连接 VPN，非常麻烦。参考小方同学的&lt;a href=&quot;http://fangpeishi.com/happy_vpn.html&quot;&gt;文章&lt;/a&gt;写了个一键登录 VPN 的 Alfred workflow，本文记录了具体过程。
&lt;/p&gt;

&lt;div id=&quot;outline-container-sec-1&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;sec-1&quot;&gt;通过脚本获得 Authenticator Token&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-1&quot;&gt;
&lt;p&gt;
安装oath-toolkit，用于通过命令行获得 token。
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;

&lt;pre class=&quot;src src-sh&quot;&gt;brew update
brew install oath-toolkit
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
创建$HOME/.otpkeys 文件，输入Token生成码，格式：
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;

&lt;pre class=&quot;src src-sh&quot;&gt;&amp;#12300;&amp;#21517;&amp;#31216;&amp;#12301;=&amp;#12300;&amp;#29983;&amp;#25104;&amp;#30721;&amp;#12301;
&amp;#20363;&amp;#65306;
&lt;span style=&quot;color: #DFAF8F;&quot;&gt;google&lt;/span&gt;=UKPPIDEALLKPYTT9
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
新建脚本文件 &lt;code&gt;./oath.sh&lt;/code&gt; ：
&lt;/p&gt;

&lt;div class=&quot;org-src-container&quot;&gt;

&lt;pre class=&quot;src src-sh&quot;&gt;&lt;span style=&quot;color: #5F7F5F;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #7F9F7F;&quot;&gt;!/bin/&lt;/span&gt;&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;bash&lt;/span&gt;
&lt;span style=&quot;color: #5F7F5F;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #7F9F7F;&quot;&gt;fork from http://superuser.com/questions/462478/is-there-a-google-authenticator&lt;/span&gt;&lt;span style=&quot;color: #7F9F7F; background-color: #3F3F3F;&quot;&gt;-desktop-client , by Peter Beckman&lt;/span&gt;

&lt;span style=&quot;color: #DFAF8F;&quot;&gt;scriptname&lt;/span&gt;=&lt;span style=&quot;color: #CC9393;&quot;&gt;`basename $0`&lt;/span&gt;
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;if&lt;/span&gt; [ -z $&lt;span style=&quot;color: #DFAF8F;&quot;&gt;1&lt;/span&gt; ]
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;then&lt;/span&gt;
&lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;$scriptname: Service Name Req&apos;d&quot;&lt;/span&gt;
&lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;&quot;&lt;/span&gt;
&lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;Usage:&quot;&lt;/span&gt;
&lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;   otp google&quot;&lt;/span&gt;
&lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;&quot;&lt;/span&gt;
&lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;Configuration: $HOME/.otpkeys&quot;&lt;/span&gt;
&lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;Format: name=key&quot;&lt;/span&gt;
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;exit&lt;/span&gt;
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;fi&lt;/span&gt;
&lt;span style=&quot;color: #DFAF8F;&quot;&gt;otpkey&lt;/span&gt;=&lt;span style=&quot;color: #CC9393;&quot;&gt;` grep ^$1 $HOME/.otpkeys | cut -d&quot;=&quot; -f 2 | sed &quot;s/ //g&quot; `&lt;/span&gt;
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;if&lt;/span&gt; [ -z $&lt;span style=&quot;color: #DFAF8F;&quot;&gt;otpkey&lt;/span&gt; ]
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;then&lt;/span&gt;
&lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;$scriptname: Bad Service Name&quot;&lt;/span&gt;
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;exit&lt;/span&gt;
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;fi&lt;/span&gt;
&lt;span style=&quot;color: #DFAF8F;&quot;&gt;token&lt;/span&gt;=&lt;span style=&quot;color: #CC9393;&quot;&gt;`/usr/local/bin/oathtool --totp -b $otpkey`&lt;/span&gt;
&lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;echo&lt;/span&gt; $&lt;span style=&quot;color: #DFAF8F;&quot;&gt;token&lt;/span&gt;
&lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;echo&lt;/span&gt; $&lt;span style=&quot;color: #DFAF8F;&quot;&gt;token&lt;/span&gt; | /usr/bin/pbcopy &lt;span style=&quot;color: #5F7F5F;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #7F9F7F;&quot;&gt;&amp;#33258;&amp;#21160;&amp;#25335;&amp;#36125;&amp;#33267;&amp;#21098;&amp;#36148;&amp;#26495;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
打开终端，执行 [脚本名] [名称] 试一试:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;

&lt;pre class=&quot;src src-sh&quot;&gt; ~  cat ~/.otpkeys
&lt;span style=&quot;color: #DFAF8F;&quot;&gt;google&lt;/span&gt;=UKPPIDEALLKPYTT9
 ~  sh ./oath.sh google
123456
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
如果 &lt;code&gt;oath.sh&lt;/code&gt; 脚本输出了6位数字，说明随机 token 生成成功。
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-sec-2&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;sec-2&quot;&gt;脚本连接 VPN&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-2&quot;&gt;
&lt;p&gt;
下载安装 Cisco AnyConnect Secure Mobility Client。
&lt;/p&gt;

&lt;p&gt;
编写脚本 &lt;code&gt;./vpn.sh&lt;/code&gt; 用于登录 VPN：
&lt;/p&gt;

&lt;div class=&quot;org-src-container&quot;&gt;

&lt;pre class=&quot;src src-sh&quot;&gt;&lt;span style=&quot;color: #5F7F5F;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #7F9F7F;&quot;&gt;!/bin/&lt;/span&gt;&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;bash&lt;/span&gt;

&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;if&lt;/span&gt; [ $&lt;span style=&quot;color: #DFAF8F;&quot;&gt;#&lt;/span&gt; -eq 1 ]
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;then&lt;/span&gt;
    &lt;span style=&quot;color: #DFAF8F;&quot;&gt;command&lt;/span&gt;=$&lt;span style=&quot;color: #DFAF8F;&quot;&gt;1&lt;/span&gt;
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;else&lt;/span&gt;
    &lt;span style=&quot;color: #DFAF8F;&quot;&gt;command&lt;/span&gt;=&lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;connect&apos;&lt;/span&gt;
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;fi&lt;/span&gt;

&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;if&lt;/span&gt; [ $&lt;span style=&quot;color: #DFAF8F;&quot;&gt;command&lt;/span&gt; == &lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;stop&apos;&lt;/span&gt; ]
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;then&lt;/span&gt;
    &lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;stop vpn&apos;&lt;/span&gt;
    /opt/cisco/anyconnect/bin/vpn disconnect
    &lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;exit&lt;/span&gt;
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;fi&lt;/span&gt;

&lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;start vpn&apos;&lt;/span&gt;
&lt;span style=&quot;color: #DFAF8F;&quot;&gt;username&lt;/span&gt;=&lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;[your ldap username]&apos;&lt;/span&gt;
&lt;span style=&quot;color: #DFAF8F;&quot;&gt;passwd&lt;/span&gt;=&lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;[your ldap password]&apos;&lt;/span&gt;&lt;span style=&quot;color: #CC9393;&quot;&gt;`sh ./oath.sh [profile_name]`&lt;/span&gt;

/opt/cisco/anyconnect/bin/vpn -s &amp;lt;&amp;lt; EOF
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;connect [vpn address]&lt;/span&gt;
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;$username&lt;/span&gt;
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;$passwd&lt;/span&gt;
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;EOF&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
然后修改 vpn.sh 中的各项信息：
&lt;/p&gt;

&lt;div class=&quot;org-src-container&quot;&gt;

&lt;pre class=&quot;src src-sh&quot;&gt;[your vpn username]
[your vpn password]
[profile_name]
[vpn address]
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-sec-2-1&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;sec-2-1&quot;&gt;连接 VPN&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-2-1&quot;&gt;
&lt;div class=&quot;org-src-container&quot;&gt;

&lt;pre class=&quot;src src-sh&quot;&gt;./vpn.sh start
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-sec-2-2&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;sec-2-2&quot;&gt;断开 VPN&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-2-2&quot;&gt;
&lt;div class=&quot;org-src-container&quot;&gt;

&lt;pre class=&quot;src src-sh&quot;&gt;./vpn.sh stop
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
至此，已经可以通过脚本一键连接、断开 VPN，不需要再输入密码。
&lt;/p&gt;

&lt;p&gt;
脚本下载：&lt;a href=&quot;https://github.com/nanma/codesnip/tree/master/scripts/cisco-vpn&quot;&gt;https://github.com/nanma/codesnip/tree/master/scripts/cisco-vpn&lt;/a&gt; 。
&lt;/p&gt;

&lt;p&gt;
但是程序员的懒惰是无止境的，脚本还需要打开终端敲命令。作为 Alfred 的忠实爱好者，第一反应就是做个 workflow 出来。
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-sec-3&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;sec-3&quot;&gt;编写 Alfred Workflow&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-3&quot;&gt;
&lt;p&gt;
因为有了前面的脚本，实现 workflow 是很简单的。只需要两个部件：「Keyword」 和「Run script」，如下图所示：
&lt;/p&gt;


&lt;div class=&quot;figure&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/images/2016/10/vpn-workflow.png&quot; alt=&quot;vpn-workflow.png&quot; /&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
其中，「Keyword」获得用户输入，将连接（start） 或是断开（stop） 的命令发给脚本，「Run script」调用前面写好的 &lt;code&gt;./vpn.sh&lt;/code&gt; 脚本完成连接、断开。
&lt;/p&gt;

&lt;p&gt;
Workflow 的下载地址：&lt;a href=&quot;https://github.com/nanma/awesome-alfred-workflows/tree/master/VPN-Toggle&quot;&gt;https://github.com/nanma/awesome-alfred-workflows/tree/master/VPN-Toggle&lt;/a&gt; 。
&lt;/p&gt;

&lt;p&gt;
参考链接：
&lt;/p&gt;
&lt;ol class=&quot;org-ol&quot;&gt;
&lt;li&gt;Any connect 命令行用法：  &lt;a href=&quot;http://www.cisco.com/c/en/us/td/docs/security/vpn_client/anyconnect/anyconnect30/administration/guide/anyconnectadmin30/ac15userguidelines.html#32168&quot;&gt;http://www.cisco.com/c/en/us/td/docs/security/vpn_client/anyconnect/anyconnect30/administration/guide/anyconnectadmin30/ac15userguidelines.html#32168&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;一键连接VPN，&lt;a href=&quot;http://fangpeishi.com/happy_vpn.html&quot;&gt;http://fangpeishi.com/happy_vpn.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Any connect 命令行参数： &lt;a href=&quot;http://stackoverflow.com/questions/21533471/cisco-anyconnect-command-line-parse-profile-or-command-line-arguments&quot;&gt;http://stackoverflow.com/questions/21533471/cisco-anyconnect-command-line-parse-profile-or-command-line-arguments&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>
        <pubDate>Sat, 22 Oct 2016 16:00:00 +0000</pubDate>
        <link>http://manan.org/2016/10/one-step-vpn</link>
        <guid isPermaLink="true">http://manan.org/2016/10/one-step-vpn</guid>
        
        
      </item>
    
      <item>
        <title>Alfred workflow开发实例</title>
        <description>&lt;p&gt;
每天写时间日志时需要输入日期，输入当天的日期比较简单，输入法一般都提供快捷键，输入 &lt;code&gt;rq&lt;/code&gt; 后，候选词中就会出现当日日期的各种格式:
&lt;/p&gt;


&lt;div class=&quot;figure&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/images/2014/12/rq.png&quot; alt=&quot;rq.png&quot; /&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
如果要输入昨天、明天、后天等相近日期，我没有找到便捷的方法。想到在Mac中可以用Alfred的扩展功能（workflow）实现这个功能，就尝试编写了一个扩展，本文记录了编写扩展的过程。
&lt;/p&gt;

&lt;div id=&quot;outline-container-sec-1&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;sec-1&quot;&gt;思路&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-1&quot;&gt;
&lt;p&gt;
Alfred是一款OS X下的启动器软件，通过它可以用键盘快捷键快速启动软件，或者执行其他更为复杂的操作，比如搜索文件、查询单词、搜索网页等。Alfred还提供了Workflows功能，用户通过它可以自己开发新的功能。
&lt;/p&gt;

&lt;p&gt;
本文要实现的效果是激活Alfred后，输入代表日期的快捷键然后回车，相应的日期复制到剪贴板中。效果如下：
&lt;/p&gt;


&lt;div class=&quot;figure&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/images/2014/12/show.png&quot; alt=&quot;show.png&quot; /&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
此时粘贴剪贴板的内容为：
&lt;/p&gt;

&lt;pre class=&quot;example&quot;&gt;
2014年12月26日 星期五
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-sec-2&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;sec-2&quot;&gt;实现过程&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-2&quot;&gt;
&lt;p&gt;
在Alfred的Workflows选项卡中点击 &lt;code&gt;+-Blank workflow&lt;/code&gt; ，输入将要新建的workflow名称，点击 &lt;code&gt;create&lt;/code&gt; 。
&lt;/p&gt;

&lt;p&gt;
此时的workflow是空的，点击右上角的 &lt;code&gt;+&lt;/code&gt; 号开始添加控件，如下图所示：
&lt;/p&gt;


&lt;div class=&quot;figure&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/images/2014/12/aquire-date.png&quot; alt=&quot;aquire-date.png&quot; /&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-sec-2-1&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;sec-2-1&quot;&gt;输入控件&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-2-1&quot;&gt;
&lt;p&gt;
图中最左侧一列是 &lt;code&gt;input-keyword&lt;/code&gt; 控件，可以为它配置相应的关键词以激活后续的功能，具体配置如下：
&lt;/p&gt;


&lt;div class=&quot;figure&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/images/2014/12/key.png&quot; alt=&quot;key.png&quot; /&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
上图中选择了 &lt;code&gt;no-argument&lt;/code&gt; , 如果需要从Alfred输入框传入参数，可以选择其他两项参数。
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-sec-2-2&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;sec-2-2&quot;&gt;动作控件&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-2-2&quot;&gt;
&lt;p&gt;
中间一列是 &lt;code&gt;action-Run Script&lt;/code&gt; ，它将根据传入的参数运行指定的脚本，配置如下：
&lt;/p&gt;


&lt;div class=&quot;figure&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/images/2014/12/run.png&quot; alt=&quot;run.png&quot; /&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
图中的命令 &lt;code&gt;python date.py zt&lt;/code&gt; , &lt;code&gt;date.py&lt;/code&gt; 是我编写的脚本，后面具体介绍。 &lt;code&gt;zt&lt;/code&gt; 是传给脚本的参数。
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-sec-2-3&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;sec-2-3&quot;&gt;输出控件&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-2-3&quot;&gt;
&lt;p&gt;
最后一列图标是 &lt;code&gt;outputs-Copy to clipboard&lt;/code&gt; ，它的作用是将前一项的输出拷贝到系统剪贴板中，它的配置如图：
&lt;/p&gt;


&lt;div class=&quot;figure&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/images/2014/12/copy.png&quot; alt=&quot;copy.png&quot; /&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
图中 &lt;code&gt;{query}&lt;/code&gt; 代表前一项的输出。
&lt;/p&gt;

&lt;p&gt;
上面的三种图标代表了一个Workflow的三个要素：输入，动作和输出，还有一个要素『触发』本文没有涉及。输入关键词后，脚本计算得到日期，然后拷贝到剪贴板中。脚本 &lt;code&gt;date.py&lt;/code&gt; 的实现如下：
&lt;/p&gt;

&lt;div class=&quot;org-src-container&quot;&gt;

&lt;pre class=&quot;src src-python&quot;&gt;&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;import&lt;/span&gt; datetime
&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;import&lt;/span&gt; sys
&lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;reload&lt;/span&gt;(sys)
sys.setdefaultencoding(&lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;utf-8&apos;&lt;/span&gt;)

&lt;span style=&quot;color: #DFAF8F;&quot;&gt;week&lt;/span&gt; = [u&lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;&amp;#19968;&apos;&lt;/span&gt;, u&lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;&amp;#20108;&apos;&lt;/span&gt;, u&lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;&amp;#19977;&apos;&lt;/span&gt;, u&lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;&amp;#22235;&apos;&lt;/span&gt;, u&lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;&amp;#20116;&apos;&lt;/span&gt;, u&lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;&amp;#20845;&apos;&lt;/span&gt;, u&lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;&amp;#26085;&apos;&lt;/span&gt;]

&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #93E0E3;&quot;&gt;delta&lt;/span&gt;(x):
    &lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;return&lt;/span&gt; {
        &lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;zt&apos;&lt;/span&gt;: -1,
        &lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;jt&apos;&lt;/span&gt;: 0,
        &lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;mt&apos;&lt;/span&gt;: 1,
        &lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;ht&apos;&lt;/span&gt;: 2,
    }[x]

&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;len&lt;/span&gt;(sys.argv) == 2:
    &lt;span style=&quot;color: #DFAF8F;&quot;&gt;query&lt;/span&gt; = sys.argv[1]
    &lt;span style=&quot;color: #DFAF8F;&quot;&gt;today&lt;/span&gt; = datetime.date.today( )
    &lt;span style=&quot;color: #DFAF8F;&quot;&gt;target&lt;/span&gt; = today + datetime.timedelta(days=delta(query))
    &lt;span style=&quot;color: #DFAF8F;&quot;&gt;ISOFORMAT&lt;/span&gt; = &lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;%Y&amp;#24180;%m&amp;#26376;%d&amp;#26085; &amp;#26143;&amp;#26399;&apos;&lt;/span&gt;
    &lt;span style=&quot;color: #DFAF8F;&quot;&gt;result&lt;/span&gt; = target.strftime(ISOFORMAT) + &lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;str&lt;/span&gt;(week[target.weekday()])
    &lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;print&lt;/span&gt; result
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
完成上面三个控件后，用鼠标将它们连接起来，就完成了workflow的编写。
&lt;/p&gt;

&lt;p&gt;
使用时，在Alfred的输入框中输入相应的关键字，如 &lt;code&gt;mt&lt;/code&gt; 代表 &lt;code&gt;明天&lt;/code&gt; ，然后回车，相应日期就复制到了剪贴板中。
&lt;/p&gt;

&lt;p&gt;
如果要发布自己开发的Workflow供别人使用，在左侧的插件名称上右键，点击 &lt;code&gt;export&lt;/code&gt; 就可以将worflow打包。
&lt;/p&gt;

&lt;p&gt;
本文实现的Alfred workflow 发布主页是：&lt;a href=&quot;https://github.com/nanma/awesome-alfred-workflows/tree/master/Aquire-Date&quot;&gt;https://github.com/nanma/awesome-alfred-workflows/tree/master/Aquire-Date&lt;/a&gt; ，欢迎使用和反馈。
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-sec-3&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;sec-3&quot;&gt;总结&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-3&quot;&gt;
&lt;p&gt;
本文以一个复制最近几日日期的扩展为例，演示了Alfred workflow的开发过程。
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>
        <pubDate>Fri, 26 Dec 2014 16:00:00 +0000</pubDate>
        <link>http://manan.org/2014/12/alfred-workflow-tutorial</link>
        <guid isPermaLink="true">http://manan.org/2014/12/alfred-workflow-tutorial</guid>
        
        
      </item>
    
      <item>
        <title>蔡学镛谈源码阅读</title>
        <description>&lt;p&gt;
最近在读一些开源项目代码，突然想起来蔡学镛老师在微博上发表过一些代码阅读方法的心得，就做了一番&lt;a href=&quot;http://weibo.com/rebol?key_word=%25E6%25BA%2590%25E4%25BB%25A3%25E7%25A0%2581&amp;is_search=1#_0&quot;&gt;搜索&lt;/a&gt;，整理如下，作为参考。
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;
如何有效阅读源代码，我的经验：1) 先阅读架构文档 2) 根据架构，将源码文件以模块（或上下层级）分类 3) 从最独立（依赖性最小）的模块代码读起 4) 阅读该模块功能文档 5) 阅读该模块源代码 6) 一边阅读一边整理「调用关系表」（很久以前我的某条微博提过）7) goto 3
&lt;/p&gt;

&lt;p&gt;
2012-12-2 10:13 来自 微博 weibo.com
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;
我傻傻地读了两星期别人的源代码，然后才发现居然有设计文档。虽然部分内容过时，和代码有差异，但还是有相当高的参考价值。我于是放下源代码，改读设计文档。&amp;#x2026; 下次我跳下去读源代码前，一定要仔细搜索有无设计文档呀！
&lt;/p&gt;

&lt;p&gt;
2012-6-16 10:27 来自 微博 weibo.com
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;
开老师这条微博刚好符合我过去这几条微博的内容主题：阅读源代码（紧急＋长期），制作「调用关系表」（重要＋短暂＋可以提升阅读源代码的效率）。
&lt;/p&gt;

&lt;p&gt;
@李开复
【不要成为紧急的奴隶，重要的事为先】某人很吃力地在锯木头，旧的没锯完，新的又送来，越堆越多，不断加班。盆友提醒他：“你的锯子钝了，所以效率甚差，磨利再锯吧！” 他说：“工作都做不完，哪有时间磨锯子？” 好心人仍不死心，问：“那你何时磨锯子呢？” 他说：“等我锯完所有木头再说。”
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;
阅读他人的源代码就像是探访亚马逊雨林，事前多做一些准备工作，虽然花时间，但是很值得。在代码丛林中，「调用关系表」就
是我的地图与 GPS。
&lt;/p&gt;

&lt;p&gt;
2012-6-14 09:04 来自 微博 weibo.com
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;
阅读源代码时，将代码顺手图像化，有助于我思考与记忆。位置、色彩、形状，这些都是我将源代码图像化时会采用的手段。
&lt;/p&gt;

&lt;p&gt;
2012-6-13 17:36 来自 微博 weibo.com
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;
这两天正在读一份源代码，之前读过同一份源代码很多次，但每次都觉得好像没有收获。不过这次读，感觉就满有收获的。&amp;#x2026; 我想，之前多次虽然貌似读不懂，但应该有积累了一些什么，才能让这次有爆发的感觉。
&lt;/p&gt;

&lt;p&gt;
2012-6-7 21:23 来自 微博 weibo.com
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;
通过 Debugger 或 Stack 的方式了解函数的调用关系，只能知道「某个」调用路径，并不全面，且比较容易失去方向感，不适合读源代码时使用。「函数调用图」通常相当杂乱，所以我个人不喜欢。我感觉用「函数调用表」会比较清晰一点，且我会持续修改这张表。
&lt;/p&gt;

&lt;p&gt;
2011-10-19 17:43 来自 微博 weibo.com
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;
阅读他人的源代码时，我会先整理出「函数调用表」，调整次序，并标注颜色。通过这个表，可以知道调用依赖关系、递归函数、函数被调用次数、函数目的。阅读代码失去方向性时，就看一下这个表。
&lt;/p&gt;


&lt;div class=&quot;figure&quot;&gt;
&lt;p&gt;&lt;img src=&quot;/images/2014/12/func-call.jpg&quot; alt=&quot;func-call.jpg&quot; /&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
2011-10-19 14:04 来自 微博 weibo.com
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;
对我来说，阅读优良的源代码，通常不是为了要学习语言的用法（Syntax），更多是要学习该语言的惯用语（Idiom）。惯用语是经年累月累积出来的优良语法模式（Syntax Pattern）。每次学到新的惯用语，就很开心。20 年前的《Advanced C++ Programming Styles and Idioms》是早期我读过关于惯用语的书。
&lt;/p&gt;

&lt;p&gt;
2011-9-27 22:43 来自 微博 weibo.com
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
个人心得：面向过程代码（C）用函数调用表更好，面向对象代码（C++）用类图更好。
&lt;/p&gt;
</description>
        <pubDate>Fri, 19 Dec 2014 16:00:00 +0000</pubDate>
        <link>http://manan.org/2014/12/on-source-code-reading</link>
        <guid isPermaLink="true">http://manan.org/2014/12/on-source-code-reading</guid>
        
        
      </item>
    
      <item>
        <title>测试IFTTT to 微博</title>
        <description>&lt;p&gt;这篇文章用来测试IFTTT to weibo的功能，使用的IFTTT recipes是 &lt;a href=&quot;https://ifttt.com/recipes/197674-publish-new-items-on-sina-weibo-from-any-feed&quot;&gt;https://ifttt.com/recipes/197674-publish-new-items-on-sina-weibo-from-any-feed&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;每次我的博客更新时，将触发新浪微博发出一条微博。&lt;/p&gt;
</description>
        <pubDate>Mon, 10 Nov 2014 00:00:00 +0000</pubDate>
        <link>http://manan.org/2014/11/test-ifttt-to-weibo</link>
        <guid isPermaLink="true">http://manan.org/2014/11/test-ifttt-to-weibo</guid>
        
        
      </item>
    
      <item>
        <title>《超体》——生命的超越</title>
        <description>&lt;p&gt;
读了和菜头在公众号的影评，我去看了《超体》。我没有绝妙的文笔评价这部电影，但仍想写写喜欢它的原因。
&lt;/p&gt;

&lt;p&gt;
我知道一些观众对《超体》有些失望，他们的评价是虎头蛇尾。因为整部电影铺陈了很长时间，似乎是在设置一个悬念：当人的大脑利用率达到100%时，将会发生什么？可是当100%到来的那一刻，电影戛然而止。
&lt;/p&gt;

&lt;p&gt;
在我看来，故事到了这里，精彩的部分已经演完了，更精彩的留给观众去想象。
&lt;/p&gt;

&lt;p&gt;
本片的精彩之处，不在于一个弱女子因为意外获得了超能力而产生逆袭，如果是这样，它和一般的超人电影有什么区别？相反，这部电影最打动我的地方，是它背后蕴含的思想：生存的意义、生命进化的过程、时间等等关于生存本质的宏大问题。
&lt;/p&gt;

&lt;p&gt;
人性本身是自私而愚蠢的，摩根·弗里曼饰演的教授担心这样的人类掌握了更多的知识后，会发生不好的事情。他从技术上预测当大脑利用率达到20%时，人将开始能操纵物质乃至操纵他人，但是预测仅此为止，他也无法想象那时的人类会变成什么样。然而，他的担心是多余的，斯嘉丽·约翰逊所饰的Lucy没有变『坏』，当她明白自己身上发生的变化时，她打电话向母亲描述自己的感受：她能回忆起自己的每一处记忆，她已经没有了痛苦、恐惧和欲望，她感到万物是一体的。打电话这一段让我十分感动，这一刻的Lucy已经成了佛陀，或者，佛陀就是大脑利用率提高了的印度王子。她的感受并非不能理解，痛苦、恐惧和欲望本就是基因趋利避害的生理机制，当她能观照自己的每一个细胞时，基因的小把戏怎可能继续得逞呢？
&lt;/p&gt;

&lt;p&gt;
Lucy证明了人类的希望：进化本身是残酷无情的，因为只有努力竞争才能生存下去，但是当进化达到一定高度时，人已经能有所察觉从而超越基因的控制，有意识的选择生命的方向。Lucy感到自己生命所剩不多时，向教授请教该做些什么。教授说，生命一代代的传承，使上一代的经验传给下一代，也许你应该把自己的知识传播出去。Lucy用生命最后的能量，把所有的知识变成了一台计算机，留给了人类。
&lt;/p&gt;

&lt;p&gt;
警察最后问道，Lucy在哪里呢？Lucy说，我无所不在。为什么说无所不在？因为她的知识、她的经验已经留下来了，成为了人类的一部分，随着人类对世界的改造，也将成为世界的一部分。这就是人类生命意义的升华：生命不再以基因本身的留存为目的，而是为了促成生命整体对宇宙的探索。
&lt;/p&gt;

&lt;p&gt;
这样说来，我们对生命和死亡是不是有了新的理解？我们的先人没有逝去，他们寄存的肉体消失了，但他们的探索和发现仍然在影响着世界，他们的经验是我们今日生活的基础，我们的经验将是未来人类的基础。从那只叫Lucy的猿人，到大草原上的印第安人，到工业革命时匆匆走过的路人，如此代代传承，生命离他们所探寻的未知之地将越来越近。
&lt;/p&gt;

&lt;p&gt;
Lucy最后制造计算机时，屋外还在进行着激烈的厮杀。可是和屋里纯白的超然环境相比，这场厮杀已经没有了批判的必要，就像我们看动物世界中猎豹追杀羚羊一样，已经成了进化史中的自然现象，谁胜谁负又有什么关系。因为生命有了更高层级的视角，对这种厮杀也就有了一种悲悯。
&lt;/p&gt;

&lt;p&gt;
电影放映时，我经常想到《三体》、佛教以及《自私的基因》，这样的思绪缠绕使我沉浸在电影引发的哲学思考中，科幻、打斗、剧情已经成了细枝末节，我想，导演已经成功了。
&lt;/p&gt;

&lt;p&gt;
影片最后问道，现在，你想用你的时间做什么呢？这是留给每个人的问题。
&lt;/p&gt;
</description>
        <pubDate>Sat, 08 Nov 2014 16:00:00 +0000</pubDate>
        <link>http://manan.org/2014/11/lucy</link>
        <guid isPermaLink="true">http://manan.org/2014/11/lucy</guid>
        
        
      </item>
    
      <item>
        <title>rsync断点续传</title>
        <description>&lt;p&gt;
项目需要从线上服务器拉大量的数据到办公网络的测试机中，由于传输过程中VPN经常断，导致数据传输失败。为了解决这个问题，写了一个脚本用来重连VPN，并重启传输任务：
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;

&lt;pre class=&quot;src src-sh&quot;&gt;&lt;span class=&quot;linenr&quot;&gt; 1: &lt;/span&gt;&lt;span style=&quot;color: #5F7F5F;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #7F9F7F;&quot;&gt;!/&lt;/span&gt;&lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;bin/&lt;/span&gt;&lt;span style=&quot;color: #7F9F7F;&quot;&gt; bash&lt;/span&gt;
&lt;span class=&quot;linenr&quot;&gt; 2: &lt;/span&gt;
&lt;span class=&quot;linenr&quot;&gt; 3: &lt;/span&gt;cp /etc/resolv.conf.bak /etc/resolv.conf
&lt;span class=&quot;linenr&quot;&gt; 4: &lt;/span&gt;/usr/sbin/vpnc-disconnect
&lt;span class=&quot;linenr&quot;&gt; 5: &lt;/span&gt;sleep 5
&lt;span class=&quot;linenr&quot;&gt; 6: &lt;/span&gt;/usr/sbin/vpnc
&lt;span class=&quot;linenr&quot;&gt; 7: &lt;/span&gt;&lt;span style=&quot;color: #DFAF8F;&quot;&gt;binary&lt;/span&gt;=&lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;rsync&quot;&lt;/span&gt;
&lt;span class=&quot;linenr&quot;&gt; 8: &lt;/span&gt;&lt;span style=&quot;color: #DFAF8F;&quot;&gt;cnt&lt;/span&gt;=$(ps aux | grep &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;\&amp;lt;$binary\&amp;gt;&quot;&lt;/span&gt; | grep -v &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;grep&quot;&lt;/span&gt; | grep -v &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;\&amp;lt;vi\&amp;gt;&quot;&lt;/span&gt; | wc -l)
&lt;span class=&quot;linenr&quot;&gt; 9: &lt;/span&gt;    &lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;if&lt;/span&gt; [ $&lt;span style=&quot;color: #DFAF8F;&quot;&gt;cnt&lt;/span&gt; -eq 0 ]; &lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;then&lt;/span&gt;
&lt;span class=&quot;linenr&quot;&gt;10: &lt;/span&gt;      &lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;Server not started yet&quot;&lt;/span&gt;
&lt;span class=&quot;linenr&quot;&gt;11: &lt;/span&gt;    &lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;linenr&quot;&gt;12: &lt;/span&gt;    &lt;span style=&quot;color: #DFAF8F;&quot;&gt;pid&lt;/span&gt;=$(ps aux | grep &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;\&amp;lt;$binary\&amp;gt;&quot;&lt;/span&gt; | grep -v &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;grep&quot;&lt;/span&gt; | grep -v &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;\&amp;lt;vi\&amp;gt;&quot;&lt;/span&gt; | awk &lt;span style=&quot;color: #DC8CC3; background-color: #3F3F3F;&quot;&gt;&apos;{print $2}&apos;)&lt;/span&gt;
&lt;span class=&quot;linenr&quot;&gt;13: &lt;/span&gt;    &lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;echo&lt;/span&gt; $&lt;span style=&quot;color: #DFAF8F;&quot;&gt;pid&lt;/span&gt;
&lt;span class=&quot;linenr&quot;&gt;14: &lt;/span&gt;    &lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;if&lt;/span&gt; [ &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;X$pid&quot;&lt;/span&gt; = &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;X&quot;&lt;/span&gt; ]; &lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;then&lt;/span&gt;
&lt;span class=&quot;linenr&quot;&gt;15: &lt;/span&gt;      &lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #CC9393;&quot;&gt;&quot;No server instance found&quot;&lt;/span&gt;
&lt;span class=&quot;linenr&quot;&gt;16: &lt;/span&gt;    &lt;span style=&quot;color: #F0DFAF; font-weight: bold;&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;linenr&quot;&gt;17: &lt;/span&gt;    &lt;span style=&quot;color: #DCDCCC; font-weight: bold;&quot;&gt;kill&lt;/span&gt; -9 $&lt;span style=&quot;color: #DFAF8F;&quot;&gt;pid&lt;/span&gt;
&lt;span class=&quot;linenr&quot;&gt;18: &lt;/span&gt;nohup rsync -av -e &lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;ssh -i /home/user/prikey&apos;&lt;/span&gt; search@10.10.65.160:/var/data /var&lt;span style=&quot;color: #DC8CC3; background-color: #3F3F3F;&quot;&gt; &amp;gt; /home/user/data.log 2&amp;gt;&amp;amp;1 &amp;amp;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
脚本会中断VPN并重连，杀掉已有的rsync进程，然后重启rsync任务。在crontab中添加这个脚本，每两个小时执行一次：
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;

&lt;pre class=&quot;src src-sh&quot;&gt;&lt;span style=&quot;color: #5F7F5F;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #7F9F7F;&quot;&gt;crontab task&lt;/span&gt;
50 */2 * * * /bin/bash /home/user/restart_service.sh &amp;gt; /home/user/restart.log 2&amp;gt;&lt;span style=&quot;color: #DC8CC3; background-color: #3F3F3F;&quot;&gt;&amp;amp;1&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
不过实际执行中发现，数据传输始终不能完成。原来在间隔的两小时内，有些大文件传不完，rsync进程重启再次从头开始传输中断 的文件，传完之前又被杀掉，如此循环往复。经过查询，rsync支持断点续传，在原来命令上加入 &lt;code&gt;-P&lt;/code&gt; 参数就可以了。把上面脚本中rsync命令改成：
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;

&lt;pre class=&quot;src src-sh&quot;&gt;nohow rsync -avP -e &lt;span style=&quot;color: #CC9393;&quot;&gt;&apos;ssh -i /home/manan/prikey&apos;&lt;/span&gt; ...
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
再次开始任务，数据传输很快完成。
&lt;/p&gt;

&lt;p&gt;
更多关于rsync续传的内容，可以参考我的wiki：&lt;a href=&quot;http://wiki.manan.org/os/linux/rsync.html&quot;&gt;http://wiki.manan.org/os/linux/rsync.html&lt;/a&gt;。
&lt;/p&gt;
</description>
        <pubDate>Thu, 06 Nov 2014 16:00:00 +0000</pubDate>
        <link>http://manan.org/2014/11/rsync-usage</link>
        <guid isPermaLink="true">http://manan.org/2014/11/rsync-usage</guid>
        
        
      </item>
    
      <item>
        <title>从WordPress到Jekyll</title>
        <description>&lt;p&gt;在细致地考虑和冲动地行动之后，我把博客系统从WordPress换成了Jekyll。&lt;/p&gt;

&lt;p&gt;从2010年起，WordPress已经陪伴了我4年。当时无意间发现了一个免费博客空间、免费的二级域名和终于找到的WordPress教程，使我搭起了第一个独立博客。第一次把自己定制的东西独立地发布到互联网上，我非常兴奋。&lt;/p&gt;

&lt;p&gt;其实在此之前，我就在寻找这样一个建站的工具，但是由于不知道自己需要的工具是什么，我搜索时都不知道用什么关键字，加上09到10年时WordPress也没有如今这么大众，资料较少，第一次寻找无果后就放下了。大四时我们寝室想一起写一个博客，记录一些好玩的技术话题，选来选去只能把这个博客建在了百度空间上。用博客服务商的网站，缺点显而易见：缺乏可定制性、产品品味差、没有个性。所以当我有了自己的网络空间和域名，尽管它像一个孤岛一样悬在遥远的赛博空间中，仍然令我感到自由和兴奋。&lt;/p&gt;

&lt;p&gt;第一个博客用了不久，这个免费的二级域名就被整体屏蔽到墙外了。从此，我走上了自己租空间、买域名的不归路。这四年来，换过几个服务器，买过几个域名，总算没有把这件事放弃掉。并且，在我的直接影响下，身边有超过5个人搭建了自己的网站。&lt;/p&gt;

&lt;p&gt;WordPress用久了，它的特点也渐渐不能满足我的需求:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;编辑不方便。格式稍微复杂，或者需要多次编辑才能完成的文章，一般是不会在浏览器的WordPress后台中进行写作的。采取的办法一般是在其他编辑器或笔记软件中完成写作，然后直接发布到WordPress中。这方面比较好的工具是Windows Live Writer，或是OneNote。但是这样发布后的文章被这些编辑软件的格式控制标签包裹，并不美观。网站上精心调试过的CSS样式就失去了意义。&lt;/li&gt;
  &lt;li&gt;性能问题。WordPress使用mysql数据库，在小内存的VPS上性能较差，经常无法连接数据库。&lt;/li&gt;
  &lt;li&gt;和wiki的分裂。我经常需要记录一些笔记，使用org-mode或者markdown记录导出的笔记是静态html格式的，而博客是动态生成的。这样两部分内容的形式彼此割裂，操作起来不方便。&lt;/li&gt;
  &lt;li&gt;维护不方便。每次博客搬家时，都要小心翼翼的导入导出mysql，配置WordPress，甚至修改链接，费事费力。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;其实上面这些缺点并不是WordPress不好，只是它不适应我的新需要了。我选择了更酷的写作方式——Jekyll。用纯文本的markdown格式写作，git进行版本控制，远程推送到服务器后自动编译并发布为静态html。不能说这是最便捷的写博客流程，确是比较干净、透明、可控的写作方式。&lt;/p&gt;
</description>
        <pubDate>Tue, 21 Oct 2014 00:00:00 +0000</pubDate>
        <link>http://manan.org/2014/10/from_wordpress_to_jekyll</link>
        <guid isPermaLink="true">http://manan.org/2014/10/from_wordpress_to_jekyll</guid>
        
        
      </item>
    
      <item>
        <title>坂井泉水</title>
        <description>&lt;!--StartFragment--&gt;
&lt;p&gt;上次在优酷闲逛时，重听了《灌篮高手》的插曲《我的朋友》，第一次留意了歌曲的演唱者——坂井泉水。网络上的留言毫不掩饰对这位日本女歌手的喜爱，出于好奇，我继续浏览了她的演出视频和个人介绍。几乎没有任何迟疑，她独特的气质立刻吸引了我。&lt;/p&gt;

&lt;p&gt;网上的歌迷称呼她姐姐，就像称呼张国荣哥哥一样自然。而她与张国荣一样的地方，除了无可取代的气质、自己作词的创作才华外，就是同样因为意外英年早逝的命运。天妒红颜，大概如此。听了几首她的歌，个人感觉，坂井泉水的歌曲风格是悲伤与希望交织的，看她的演唱会视频，我很容易想到邓丽君、陈晓旭以及其他一些名字。&lt;/p&gt;

&lt;p&gt;小学毕业时我有一盘磁带里有那首《我的朋友》，当时应该正是坂井所在的乐队ZARD当红的时候，但那时我不知道这样一位女歌手。后来听得烂熟的柯南主题曲《转动命运的赌盘》也是坂井唱的。坂井的歌总是充满希望的力量，即使抒发悲伤也没有消沉的感觉。因为这种风格，她的早逝更让人感慨：悲剧总是把希望毁灭的过程。我最近在手机里下载了几首她的经典歌曲，下班路上听感到很快乐。&lt;/p&gt;

&lt;p&gt;想到十几年前用磁带听过的女歌手这样美丽，我感到幸福；但在她离开7年后我才第一次知道她的名字，又有些遗憾——我本来也可以有一位偶像的。
&lt;!--EndFragment--&gt;
&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; title=&quot;NewImage.png&quot; alt=&quot;NewImage&quot; src=&quot;/images/wp/2014/10/NewImage.png&quot; width=&quot;354&quot; height=&quot;450&quot; border=&quot;0&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 05 Oct 2014 23:09:00 +0000</pubDate>
        <link>http://manan.org/2014/10/izumi_sakai</link>
        <guid isPermaLink="true">http://manan.org/2014/10/izumi_sakai</guid>
        
        
        <category>随笔</category>
        
      </item>
    
      <item>
        <title>平凡之路不简单</title>
        <description>&lt;!--StartFragment--&gt;
&lt;div style=&quot;direction: ltr; border-width: 100%;&quot;&gt;
&lt;div style=&quot;direction: ltr; margin-top: 0in; margin-left: 0in; width: 6.109in;&quot;&gt;
&lt;div style=&quot;direction: ltr; margin-top: 0in; margin-left: 0in; width: 6.109in;&quot;&gt;
&lt;p style=&quot;margin: 0in; font-family: SimSun; font-size: 10.5pt;&quot;&gt;看《平凡之路》时，到处都在转关于朴树的文章，讲他年少成名后的经历。我当时想，平凡之路只属于朴树、韩寒们，因为他们曾经名动天下，已经不用再证明什么。&lt;/p&gt;
&lt;p style=&quot;margin: 0in; font-family: SimSun; font-size: 10.5pt;&quot;&gt;又想起来《挪威的森林》中有段话可以描述这种感觉，特意找了来：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p style=&quot;margin: 0in; font-family: SimSun; font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-style: italic; font-family: SimSun;&quot;&gt;喂！你知道当个有钱人最大的好处是什么吗？”&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0in; font-family: SimSun; font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-style: italic; color: #595959; font-size: 11pt;&quot;&gt;“不知道！”&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0in; font-size: 11.0pt; color: #595959;&quot;&gt;&lt;span lang=&quot;zh-CN&quot; style=&quot;font-style: italic; font-family: SimSun;&quot;&gt;“就是你可以说‘我没钱’三个字。比如说我邀同学一起去干嘛的，她可以说：“不行！我现在没钱。”换作是我的话，我可不能这么说了。因为如果我说：『我现在没钱。』那就是真的没钱，很惨吧？这道理就好比一个美人说：『我今天很难看，不想出门。』一样，如果你是个丑八怪，说这话一定会被嘲笑的。我当时过的就是这种日子。到去年为止，整整六年。”&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p style=&quot;margin: 0in; font-family: SimSun; font-size: 10.5pt;&quot;&gt;又想起傅雷写过的：不经过战斗的舍弃是虚伪的，不经历磨练的超脱是轻佻的。平凡之路并不简单。&lt;/p&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
</description>
        <pubDate>Sun, 05 Oct 2014 22:16:00 +0000</pubDate>
        <link>http://manan.org/2014/10/the_road</link>
        <guid isPermaLink="true">http://manan.org/2014/10/the_road</guid>
        
        
        <category>随笔</category>
        
      </item>
    
  </channel>
</rss>
