golang daemon sample

分类:golang | 作者:admin | 发表于2012/12/12 没有评论  

最近好多人问如何用golang启动一个daemon,其实思路跟之前的python启daemon方式一样。

贴一段代码:

继续阅读 »

Tag:

osx tips: 让Terminal和Finder互动起来

分类:OSX | 作者:admin | 发表于2012/10/10 没有评论  

前提条件

首先,需要安装zsh,并开启osx插件。
强烈建议使用zsh为默认shell,并参考底部文章中使用oh-my-zsh。

Tips

从Terminal打开Finder

借助原生的open命令来做。

$ open .
在Terminal中使用Finder的当前路径
# 显示Finder当前目录的ls列表
$ ls -al $(pfd)
# 显示Finder选中文件的ls列表
$ ls -al $(pfs)
# 转到Finder的当期目录
$ cdf
在Terminal中使用快速预览
$ quick-look 黑衣人.mkv
快速将man命令内容格式化到pdf并打开
$ man-preview ifconfig
Terminal中讲文件移到回收站
$ trash 黑衣人.mkv

相关链接

vim tips:快捷键被覆盖了怎么办

分类:VIM | 作者:admin | 发表于2012/09/06 没有评论  

mswin.vim中实现了windows下的一部分快捷键兼容,包括Ctrl+C、Ctrl+V、Ctrl+S、Ctrl+A等等。

以Ctrl+A为例,一旦执行了mswin.vim,就找不到数字累加功能了。

这里提供一种手段来解决此类问题:

首先通过verbose来查看想要的快捷键在何处被绑定:

:verbose map <C-A>
x  <C-A>       * <C-C>ggVG
        Last set from /usr/share/vim/vim73/mswin.vim
s  <C-A>       * <C-C>gggH<C-O>G
        Last set from /usr/share/vim/vim73/mswin.vim
o  <C-A>       * <C-C>gggH<C-O>G
        Last set from /usr/share/vim/vim73/mswin.vim
n  <C-A>       * gggH<C-O>G
        Last set from /usr/share/vim/vim73/mswin.vim
Press ENTER or type command to continue

可以通过这种方式取消这个绑定(使用默认方式):

:nunmap <C-a>

试试看,是不是Ctrl+A回来了?

然后知道了绑定位置后,在这绑定之前就可以做一个另外快捷键的绑定,这样就既都不会被破坏掉原始得配置,又可以使用想要的功能了:

nnoremap <C-a> <C-p>
...
source $VIMRUNTIME/mswin.vim

vim tips: 终端中粘贴文本小技巧

分类:VIM | 作者:admin | 发表于2012/09/05 没有评论  

在终端中使用文本粘贴,vim会当做串行文本输入来处理,会导致格式错乱,比如:

line1
    line2
        line3
            ...

官方提供了一种模式是不会有自动缩进和自动注释的,使用方法如下:

:set paste
# do paste
:set nopaste
Tag:

在iTerm2中使用Zmodem的方法

分类:OSX | 作者:admin | 发表于2012/08/29 3条评论 

iTerm通过trigger的方式可以使用sz、rz命令方便的通过Terminal在远程主机文件传输。

设置方法

首先需要安装iTerm Build 1.0.0.20120724以上版本,因为从这个版本开始支持trigger。

然后使用port安装sz、rz:

$ sudo port install lrzsz

通过链接中“iterm2-zmodem”的说明,分别把iterm2-recv-zmodem.sh、iterm2-send-zmodem.sh放到/usr/local/bin/下,并加上可执行权限。

这里需要做一点小改动,脚本本身需要执行mac的sz、rz,port安装后是在/opt/local/bin/下,而作者的是/usr/local/bin/下,这里需要手动修改一下。

这是修改后的:

iterm2-recv-zmodem.sh

#!/bin/bash
# Author: Matt Mastracci (matthew@mastracci.com)
# AppleScript from http://stackoverflow.com/questions/4309087/cancel-button-on-osascript-in-a-bash-script
# licensed under cc-wiki with attribution required
# Remainder of script public domain
 
FILE=`osascript -e 'tell application "iTerm" to activate' -e 'tell application "iTerm" to set thefile to choose folder with prompt "Choose a folder to place received files in"' -e "do shell script (\"echo \"&(quoted form of POSIX path of thefile as Unicode text)&\"\")"`
if [[ $FILE = "" ]]; then
    echo Cancelled.
    # Send ZModem cancel
    echo -e \\x18\\x18\\x18\\x18\\x18
    echo \# Cancelled transfer
    echo
else
    echo $FILE
    cd "$FILE"
    #/usr/local/bin/rz
    /opt/local/bin/rz
    echo \# Received $FILE
    echo
fi

iterm2-send-zmodem.sh

#!/bin/bash
# Author: Matt Mastracci (matthew@mastracci.com)
# AppleScript from http://stackoverflow.com/questions/4309087/cancel-button-on-osascript-in-a-bash-script
# licensed under cc-wiki with attribution required
# Remainder of script public domain
 
FILE=`osascript -e 'tell application "iTerm" to activate' -e 'tell application "iTerm" to set thefile to choose file with prompt "Choose a file to send"' -e "do shell script (\"echo \"&(quoted form of POSIX path of thefile as Unicode text)&\"\")"`
if [[ $FILE = "" ]]; then
    echo Cancelled.
    # Send ZModem cancel
    echo -e \\x18\\x18\\x18\\x18\\x18
    echo \# Cancelled transfer
    echo
else
    echo $FILE
    #/usr/local/bin/sz "$FILE"
    /opt/local/bin/sz "$FILE"
    echo \# Received $FILE
    echo
fi

修改iTerm2的default trigger(iTerm偏好设置-> Profiles -> Default -> Advanced -> Triggers的Edit按钮):

Regular expression: \*\*B0100
Action: Run Silent Coprocess
Parameters: /usr/local/bin/iterm2-send-zmodem.sh
 
Regular expression: \*\*B00000000000000
Action: Run Silent Coprocess
Parameters: /usr/local/bin/iterm2-recv-zmodem.sh

相关链接

iTerm2下载:

http://code.google.com/p/iterm2/downloads/list

iTerm2 trigger说明:

http://www.iterm2.com/triggers.html#/section/home

iterm2-zmodem脚本:

https://github.com/mmastrac/iterm2-zmodem

关于Flask的默认session

分类:python | 作者:admin | 发表于2012/08/20 没有评论  

Flask的默认session利用了Werkzeug的SecureCookie,把信息做序列化(pickle)后编码(base64),放到cookie里了。

过期时间是通过cookie的过期时间实现的。

为了防止cookie内容被篡改,session会自动打上一个叫session的hash串,这个串是经过session内容、SECRET_KEY计算出来的,看得出,这种设计虽然不能保证session里的内容不泄露,但至少防止了不被篡改。

另外,过期时间是这样来设置:

from datetime import timedelta
 
session.permanent = True
app.permanent_session_lifetime = timedelta(minutes=5)
session['key'] = value

详情参见源码:
$PYTHONPATH/site-packages/flask/sessions.py

官方的Snippets给出了一则更好的客户端Session:
http://flask.pocoo.org/snippets/51/

Tag:

sublime2试用手记

分类:VIM | 作者:admin | 发表于2012/07/18 没有评论  

评价

总起来说是一款很牛X的编辑器,只是习惯了VIM的高效再去评判一些编辑器就总会带有一些“偏见”。

截图:

亮点
  1. 可以使用vim的基本快捷键,这样对于vimer切换到此环境有很大帮助。
  2. 打开大文件速度很快,与vim相差无几,但比vim更人性化的加入了进度条。
  3. 整体的UI设计非常赞,与gvim不在一个量级。
  4. 代码缩略图非常棒。
  5. 支持textmate形式的缩进,不过与vim的snippetmate相比,无优势。
  6. 支持Windows/Linux/Mac三大平台。
  7. 开发进度很快,势头很猛,值得期待。
  8. 具备多处同时编辑功能。

不爽
  1. 好多快捷键要改变习惯。
  2. 索引树没NerdTree好用。
  3. 又要用鼠标了。
  4. 不支持:命令,这个很是不爽。

使用方法

如何开启VIM模式

按下ctrl+shift+p -> 输入”settings user”

{
	"ignored_packages": []
}

一个不错的入门教程:

http://lucifr.com/139225/sublime-text-2-tricks-and-tips/

Tag:

一款git增强版工具legit

分类:linux | 作者:admin | 发表于2012/04/17 没有评论  

legit是什么

legit的灵感来自GitHub for Mac。 对branch操作做了很好的人性化设计。

主页在此:https://github.com/kennethreitz/legit

在README.rst中可以看到更详细的帮助。

用legit做分支操作

# 查看所有分支
$ legit branches
* master (published)
 
# 创建一个分支
$ legit sprout autocomplete
Branching master to autocomplete.
$ legit branches
* autocomplete (unpublished)
master (published)
 
# 本地的分支需要通过publish与github同步
$ legit publish
Publishing autocomplete.
$ legit branches
* autocomplete (published)
master (published)
 
# 删除一个分支
$ legit graft autocomplete
Switching to master.
Grafting autocomplete into master.
Already up-to-date.
Deleted branch autocomplete (was f0c3f4f).
 
# 同步当前分支
$ legit sync
Pulling commits from the server.
Already up-to-date.
Pushing commits to the server.
Tag:

使用xinput来禁用触摸板(touchpad)

分类:linux | 作者:admin | 发表于2012/04/08 没有评论  

什么是xinput

xinput是操作输入设备(键盘、鼠标等)命令,同时具备输出设备列表、设置设备行为等功能。
使用man xinput来查看具体参数说明。

用xinput禁用touchpad

以我的Thinkpad X220为例,先列出所有input设备。

$ xinput --list
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ Lenovo ThinkPad USB Laser Mouse id=10 [slave pointer (2)]
⎜ ↳ TPPS/2 IBM TrackPoint id=13 [slave pointer (2)]
⎜ ↳ SynPS/2 Synaptics TouchPad id=12 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ Power Button id=6 [slave keyboard (3)]
↳ Video Bus id=7 [slave keyboard (3)]
↳ Sleep Button id=8 [slave keyboard (3)]
↳ Integrated Camera id=9 [slave keyboard (3)]
↳ AT Translated Set 2 keyboard id=11 [slave keyboard (3)]
↳ ThinkPad Extra Buttons id=14 [slave keyboard (3)]

找到了x220的touchpad id是12。
用以下方法禁用掉。

$ xinput set-int-prop 12 "Device Enabled" 8 0

最后的那个数字的“0/1”即为“禁用/启用”。

一个python的daemon类

分类:python | 作者:admin | 发表于2012/03/15 没有评论  

通过此类可做到迅速将一个方法包装成daemon。

# -*- coding: utf-8 -*-
# Daemon module
# @auth     jaypei
# @email    jaypei97159@gmail.com
 
import sys, os, time, atexit, signal
 
class Daemon(object):
    """A generic daemon class.
 
    Usage: subclass the daemon class and override the run() method."""
 
    def __init__(self, pidfile, def_output=False):
        self.pidfile = pidfile
        self.def_output = def_output
 
    def daemonize(self):
        """Deamonize class. UNIX double fork mechanism."""
 
        try:
            pid = os.fork()
            if pid > 0:
                # exit first parent
                sys.exit(0)
        except OSError, err:
            sys.stderr.write('fork #1 failed: %s\n' % str(err))
            sys.exit(1)
 
        # decouple from parent environment
        os.chdir('/')
        os.setsid()
        os.umask(0)
 
        # do second fork
        try:
            pid = os.fork()
            if pid > 0:
 
                # exit from second parent
                sys.exit(0)
        except OSError, err:
            sys.stderr.write('fork #2 failed: %s\n' % str(err))
            sys.exit(1)
 
        # redirect standard file descriptors
        if not self.def_output:
            sys.stdout.flush()
            sys.stderr.flush()
            si = open(os.devnull, 'r')
            so = open(os.devnull, 'a+')
            se = open(os.devnull, 'a+')
 
            os.dup2(si.fileno(), sys.stdin.fileno())
            os.dup2(so.fileno(), sys.stdout.fileno())
            os.dup2(se.fileno(), sys.stderr.fileno())
 
        # write pidfile
        atexit.register(self.delpid)
 
        pid = str(os.getpid())
        fp = open(self.pidfile,'w+')
        fp.write(pid + '\n')
        fp.close()
 
    def delpid(self):
        os.remove(self.pidfile)
 
    def start(self):
        """Start the daemon."""
 
        # Check for a pidfile to see if the daemon already runs
        try:
            fp = open(self.pidfile,'r')
            pid = int(fp.read().strip())
            fp.close()
        except IOError:
            pid = None
 
        if pid:
            message = "pidfile %s already exist. " + \
                    "Daemon already running?\n"
            sys.stderr.write(message % self.pidfile)
            sys.exit(1)
 
        # Start the daemon
        self.daemonize()
        self.run()
 
    def stop(self):
        """Stop the daemon."""
 
        # Get the pid from the pidfile
        try:
            fp = open(self.pidfile,'r')
            pid = int(fp.read().strip())
            fp.close()
        except IOError:
            pid = None
 
        if not pid:
            message = "pidfile %s does not exist. " + \
                    "Daemon not running?\n"
            sys.stderr.write(message % self.pidfile)
            return # not an error in a restart
 
        # Try killing the daemon process    
        try:
            while 1:
                os.kill(pid, signal.SIGTERM)
                time.sleep(0.1)
        except OSError, err:
            e = str(err.args)
            if e.find("No such process") > 0:
                if os.path.exists(self.pidfile):
                    os.remove(self.pidfile)
            else:
                print (str(err.args))
                sys.exit(1)
 
    def restart(self):
        """Restart the daemon."""
        self.stop()
        self.start()
 
    def run(self):
        """You should override this method when you subclass Daemon.
 
        It will be called after the process has been daemonized by 
        start() or restart()."""
        raise NotImplementedError
 
    def doShell(self, argv):
        prog_name = argv[0]
 
        def usage():
            print >>sys.stderr, "Usage: %(prog)s start|stop|restart" % {
                    "prog": prog_name }
            sys.exit(0)
 
        if len(argv) != 2:
            usage()
            print
 
        command = argv[1]
        if command == "start":
            self.start()
        elif command == "stop":
            self.stop()
        elif command == "restart":
            self.restart()
        else:
            usage()
Tag: