V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
clino
V2EX  ›  Python

用 gevent 写了一个并发执行命令的小工具 prun

  •  2
     
  •   clino ·
    zhangchunlin · 2014-08-05 16:29:52 +08:00 · 3866 次点击
    这是一个创建于 3890 天前的主题,其中的信息可能已经有所发展或是发生改变。


    #! /usr/bin/env python
    #coding=utf-8
    import gevent
    from gevent.subprocess import Popen, PIPE
    import sys
    def run(cmd,name="",index=1,color=True):
    fc = 32 + index%5
    if name:
    if color:
    name = "\033[%dm%s\033[0m"%(fc,name)
    sub = Popen([cmd], stdout=PIPE, stderr=PIPE, shell=True)
    def print_stdout():
    for l in sub.stdout:
    print "%s: %s"%(name,l),
    def print_stderr():
    for l in sub.stderr:
    if color:
    l = "\033[31m%s\033[0m"%(l)
    print >> sys.stderr,"%s: %s"%(name,l)
    g1 = gevent.spawn(print_stdout)
    g2 = gevent.spawn(print_stderr)
    sub.wait()
    g1.kill()
    g2.kill()
    end_str = "--- end ---"
    if color:
    end = "%s: \033[31m%s\033[0m"%(name,end_str)
    else:
    end = "%s: %s"%(name,end_str)
    print end
    return sub.returncode
    def prun(cmds,color=True):
    def get_name_cmd(cmd,index):
    if type(cmd)==type(""):
    name = "cmd%d"%(index)
    cmd2 = cmd
    else:
    name,cmd2 = cmd
    return name,cmd2
    l = []
    for index,cmd in enumerate(cmds):
    name,cmd2 = get_name_cmd(cmd,index+1)
    fc = 32 + index%5
    if color:
    name2 = "\033[%dm%s\033[0m"%(fc,name)
    else:
    name2 = name
    print "%s %s: %s"%(index+1,name2,cmd2)
    g = gevent.spawn(run,cmd=cmd2,name=name,index=index,color=color)
    l.append(g)
    print
    gevent.joinall(l)
    for index,g in enumerate(l):
    if g.value!=0:
    name,cmd2 = get_name_cmd(cmds[index],index+1)
    errmsg = "error: '%s' return %s"%(cmd2,g.value)
    if color:
    errmsg = "\033[31m%s\033[0m"%(errmsg)
    print
    print >> sys.stderr,errmsg
    sys.exit(g.value)
    def main():
    from optparse import OptionParser
    parser = OptionParser()
    usage = 'usage: %prog [options] "name1:cmd1" "name2:cmd2"...'
    parser.set_usage(usage)
    parser.add_option('--no-color', dest='no_color', default=False, help="no color when print stdio", action='store_true')
    options, args = parser.parse_args()
    def cmdsplit(cmd):
    l = cmd.split(":")
    if len(l)>1:
    return l[0],":".join(l[1:])
    return cmd
    cmds = map(cmdsplit,args)
    if cmds:
    prun(cmds, not options.no_color)
    else:
    parser.print_help()
    if __name__ == '__main__':
    main()
    view raw prun hosted with ❤ by GitHub
    2 条回复    2014-08-06 14:05:12 +08:00
    poke707
        1
    poke707  
       2014-08-05 18:58:04 +08:00
    很方便,真合适有时想并发执行些一次性二代小任务,又懒得写code
    希望LZ能发布到pip :)
    clino
        2
    clino  
    OP
       2014-08-06 14:05:12 +08:00
    @poke707 发布到pip指的是上载到pypi上吗? 有点麻烦,本来想就是一个小工具就贴到gist上了,不过如果上载到pypi上会方便使用的话之后抽空做一下好了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5235 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 07:59 · PVG 15:59 · LAX 00:59 · JFK 03:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.