1. 19 Nov 2012

    SSH/SSHD的常用配置和用法

    ssh是一个常用的命令,GNU/Linux 和 OS X默认安装。sshd亦是服务器居家必备。

    sshd配置:/etc/ssh/sshd_config 禁止密码登陆,禁止root登陆

    这是一个血的教训,最近身边的一台服务器被攻击,原因是允许了root用密码登陆,结果被别人暴力破解。

    # edit file: /etc/ssh/sshd_config
    ChallengeResponseAuthentication no
    PasswordAuthentication no
    UsePAM no
    PermitRootLogin no

    ssh 配置: ~/.ssh/config

    可以把一些常访问的ssh服务器的信息放在 ~/.ssh/config

    例如经常敲这样的命令:以someone用户登陆example.com,它的端口是2323,并且启用压缩

    ssh -p 2323 -C 

    加入这样的配置后

    Host example
        HostName example.com
        User someone
        Port 2323
        Compression yes

    就可以直接 ssh example登陆了,意思和敲完整命令的一样

    另外,如果加入

    ControlMaster auto
    ControlPath /tmp/ssh_mux_%h_%p_%r
    ControlPersist 10h

    就相当于keep-alive,Ctrl-D退出后,并没有真正退出,下次再登陆时,会快不少。这个对需要远程执行命令时,比较有用。

    X11转发

    我在公司,是通过Macbook Air ssh 登陆到一台强大的服务器上进行开发,起远程的Emacs,并且把Emacs的界面放在Air上,使Air成为X Server,这样Emacs做为一个X11程序,而不是做为终端程序,避免键冲突。 SSH 的-X -Y参数就能帮助实现这个

    ssh -p 2323 -C -X -Y 

    这是可以起example.com的X程序,界面在本地,如jconsole, jvisualvm,emacs等,倒是方便。

    端口映射

    例如本地并没有装MySQL服务,有个程序需要访问本地的MySQL服务。可以通过ssh端口转发,把到本地的3306的请求转发给example.com的127.0.0.1:3306。

    ssh -L localhost:3306:localhost:3306 -Nf 

    这样可以绕过防火墙,它不需要example.com对外开放3306端口。

    反向端口映射

    你的机器在内网,外面访问不了。你回家后还想访问本机的3389端口,继续干活。你有一台外网的机器,上面有sshd,可以通过:

    ssh -R :3389:localhost:3389 -Nf 

    这样你就可以在另外地方通过访问example.com:3389,而达到访问本机3389的目的。

    自建简易翻墙

    ssh -D :3128 

    这样就在本地建立了一个SOCKS代理,SOCKS工作在TCP层。浏览器等可以设置代理为SOCKS 127.0.0.1:3128。这样浏览器和example.com之间建立一条加密的安全通道,如果example.com在X外,你就绕过了。

    Rssminer有很多抓取任务,有不少在X外,本地开发时,就是通过一个支持SOCKS的HTTP clientssh -D 完成抓取任务的。

    脚本远程命令

    ssh可被脚本用于执行远程命令,使admin任务脚本化,自动化。 例如:

    ssh  uname

    相当于登陆到example.com机器上,执行uname命令,结果输出到控制台,退出

    Rssminer 用此来部署代码后,重启服务

  2. 14 Nov 2012

    defhandler, a clojure macro aid define ring handler

    Currently, I am working at AVOS Systems’s China team. I am in a group responsible for building meiweisq, The Delicious web service, but for Chinese users, and using Clojure!

    We are using Ring and Compojure. Ring’s request/response abstraction is great, Compojure’s defroutes family functions get its job done perfectly. We are just happy using it.

    A ring handler is just a plain Clojure function, passing a request map, return a response map:

    (defn handler [req]
      ;; return a map of keys [:status :body :headers]
      )

    There are some boilerplate code, in this pattern:

    ;;; get the params
    (let [{:keys [id tag]} (:params req)
          limit (min 30 (to-int (or (:limit (:params req)) 15)))
          offset (to-int (or (:offset (:params req)) 0))]
      ;; do work with these params
      )

    They are repeated in the source code. Repeats are bad. Macro comes to the rescue:

    (defmacro defhandler [handler bindings & body]
      (let [req (bindings 0)
            bindings (rest bindings)
            ks (map (fn [s] (keyword (name s))) bindings)
            vals (map (fn [k]
                        ;; limit and offset are special, set the default value, guard large
                        ;; limit, convert them to int
                        (cond (= :limit k) `(min 30 (to-int (or (~k (:params ~req)) 15)))
                              (= :offset k) `(to-int (or (~k (:params ~req)) 0))
                              ;; more pattens here, something like
                              ;; (= :uid k) code to get user id
                              :else `(~k (:params ~req)))) ks)]
        `(defn ~handler [~req]
           (let [~@(interleave bindings vals)]
             ~@body))))

    example usage

    (defhandler list-feeds [req id limit offset]
      {:status 200
       :body (str "the subscription id: " id
                  "limit:" limit
                  "offset:" offset)})

    Macroexpand to

    (defn list-feeds [req]
      (let [id (:id (:params req))
            limit (min 30 (to-int (or (:limit (:params req)) 15)))
            offset (to-int (or (:offset (:params req)) 0))]
        {:status 200
         :body (str "the subscription id: " id
                    "limit:" limit
                    "offset:" offset)}))

    Boilerplate killed. I am happy now.

    By the way, to-int source code:

    (defn to-int [s] (cond
                      (string? s) (Integer/parseInt s)
                      (instance? Integer s) s
                      (instance? Long s) (.intValue ^Long s)
                      :else 0))
  3. 11 Nov 2012

    Emacs高亮光标下的单词

    用Emacs一年半了,刚开始时用了 Emacs Starter Kit, 它很不错,帮了我很多:

    The Starter Kit provides a more pleasant set of defaults than you get normally with Emacs. It was originally intended for beginners, but it offers a nicely augmented working environment for anyone using Emacsø

    最近,产品经理在构思产品思路,拉大家开会。工欲善其事,必先利其器, 我忙里偷闲,打磨打磨工具,为接下来的战斗积蓄势能。 重新整理了Emacs的配置文件,去掉了Emacs Starter Kit,写了一些elisp函数 提高我作为程序员的生活品质, 在github的代码

    feng-lastchange

    简化并改进了原来写的类似于 Eclipse Ctrl-q , Intellj Shift+Command+Delete Last Edit Location

    feng-highlight

    Eclipse和Intellj都有高亮光标下变量,函数等功能,挺实用。 image

    Emacs也有类似的:idle-highlight-mode

    我常常这样干活:一个变量,M-b…到开始,C-sC-w….选择,C-s搜索定位,如 果idle-highlight-mode有这样的附加功能:

    高亮当前buffer中光标下的东东,能快速到上一个/下一个出现的地方,有替换功能

    我的生活品质会提高不少。

    自己动手,丰衣足食

    昨晚,光棍节的前一晚,熬到两点,敲了几十行 elisp代码 实现了我想要的快捷键

    (global-set-key (kbd "M-i") 'feng-highlight-at-point)
    • M-i 执行 feng-highlight-at-point 启动高亮
    • M-n 上一个
    • M-p 下一个
    • M-r 替换

    image

    今天光棍节,上午试着用了一会儿,截图就是应用于golang。

    向上/向下/替换是不错的附加功能,多么希望Eclipse/Intellj也有类似顺手的功能和快捷键。

    对比Eclipse/Intellj, 他们对代码有语义分析,我这仅基于文本。也有好处: if, else照样高亮。

    下午陪女朋友去逛街买衣服了。

    完整代码

    (require 'thingatpt)
    
    (defface feng-highlight-at-point-face
      `((((class color) (background light))
         (:background "light green"))
        (((class color) (background dark))
         (:background "royal blue")))
      "Face for highlighting variables"
      :group 'feng-highlight)
    
    (defvar current-highlighted nil)
    (make-variable-buffer-local 'current-highlighted)
    
    (defun feng-at-point-prev ()
      (interactive)
      (when current-highlighted
        (unless (re-search-backward
                 (concat "\\<" (regexp-quote current-highlighted) "\\>") nil t)
          (message "search hit TOP, continue from BOTTOM")
          (goto-char (point-max))
          (feng-at-point-prev))))
    
    (defun feng-at-point-next ()
      (interactive)
      (when current-highlighted
        (forward-char (+ 1 (length current-highlighted))) ; more out of current
        (if (re-search-forward
             (concat "\\<" (regexp-quote current-highlighted) "\\>") nil t)
            (backward-char (length current-highlighted))
          (backward-char (+ 1 (length current-highlighted)))
          (message "search hit BOTTOM, continue from TOP")
          (goto-char (point-min))
          (feng-at-point-next))))
    
    (defun feng-at-point-replace ()
      (interactive)
      (when current-highlighted
        (save-excursion
          (goto-char (point-min))           ;; back to top
          (feng-at-point-next)              ;; find first
          (setq isearch-string current-highlighted)
          (isearch-query-replace))))
    
    (defvar feng-highlight-at-point-keymap
      (let ((map (make-sparse-keymap)))
        (define-key map (kbd "M-n") 'feng-at-point-next)
        (define-key map (kbd "M-r") 'feng-at-point-replace)
        (define-key map (kbd "M-p") 'feng-at-point-prev)
        map))
    
    (defun feng-highlight-at-point ()
      (interactive)
      (remove-overlays (point-min) (point-max) 'feng-highlight t)
      (let* ((target-symbol (symbol-at-point))
             (target (symbol-name target-symbol)))
        (when target-symbol
          (setq current-highlighted target)
          (save-excursion
            (goto-char (point-min))
            (let* ((regexp (concat "\\<" (regexp-quote target) "\\>"))
                   (len (length target))
                   (end (re-search-forward regexp nil t)))
              (while end
                (let ((ovl (make-overlay (- end len) end)))
                  (overlay-put ovl 'keymap feng-highlight-at-point-keymap)
                  (overlay-put ovl 'face 'feng-highlight-at-point-face)
                  (overlay-put ovl 'feng-highlight t))
                (setq end (re-search-forward regexp nil t))))))))
    
    (provide 'feng-highlight)
  4. 31 Oct 2012

    又买了个显示器,这次稍大

    这个月,入手戴尔(DELL)UltraSharp U2713HM 27英寸,分辨率达2560x1440,比以前用的戴尔UltraSharp U2311H 1920x1080分辨率高78%,而显示面积仅大38%,像素更密集,显示更精细。用了一周多了,感觉非常好,是一个不错的升级。

    1. 宽变成了2560,Chrome developer tools 可以非常方便的dock to right,而1920则显得有些拥挤
    2. 字略显小,调大一号后,很清楚。
    3. Intellj/Eclipse可以横着两列代码,左右还可以有工具栏,4列。调试程序方便多了
    4. 以前Emacs分3列,每列只有78个字符。现在可以有96个,在看别人代码时,方便不少。
    5. 每屏可以显示更多行的代码。对网页,则可以显示更多的内容。
    6. Photoshop方便了不少。

    它有些把我惯坏了,我都有些不习惯在Air的1440x900的分辨率的13.3寸屏幕上敲代码了。

    回想大一正式接触计算机,已经前后买个5个笔记本,2个台式机,3个显示器了。 从第一个二手的Thinkpad, 192M内存,Celeron 550MHZ, 12G硬盘到现在的自 配台式机,Intel i7 ,4核心8线程,16G内存,1T硬盘,6年的时间发 生了很大变化。

    大学时期,省钱从一个二手笔记本升级成另外一个快一点的二手笔记本。大四3月实习所得配了个“很快”的台式机。

    省了点钱,就忍不住买硬件,因为更好的硬件带来的是效率的提升,是可以更方 便的做些实验。比如最近为Rssminer做的,用Simhash来排出近似文章。由于硬 件允许,我可以为线上的近百万文章算一遍simhash,以暴力的方式遍历计算得 出近似比例,做出web界面查看近似文章,发现有误判情况,尝试另外的hash算 法,调整参数,快速迭代,优化。

    硬件的投入是相对便宜的,而节省了时间是划算的

    如果你也赞同硬件的投入是划算的,可以考虑联系我,我可以用你提供的大显示 器快速写出强悍的程序。

  5. 26 Oct 2012

    最近和同事闹不愉快,要反思。要冷静

    最近,因为小事和同事,在工作中,发生争执,搞的都不愉快。需要反思。领导找我谈过话。自己意识到,脾气暴躁了,实在不应该。

    团队协作这些道理我也知道,可做起来却变了味。吵后想想,其实可以没什么大事,我少说一句可能就没有那些问题。

    感谢同事们对我的宽容。

    需要平静下来,认真做事,踏实做人

    1. 工作,和lili,邹剑,小敏,俊文一起好好做美味书签,做到最好。我们可能还需要很多讨论,需要做到简单,好用,易用。
    2. 系统搞go语言,需要知道细节,不能止表面。写一个lisp 解释器作为练习
    3. 再系统复习一下CSS
    4. 学习Clojure的实现,试着解释Rssminer需要花2s才能启动
    5. 完善Rssminer的Android程序