Skip to content

Instantly share code, notes, and snippets.

@zhangchunlin
Created August 5, 2014 08:11
Show Gist options
  • Save zhangchunlin/05576572b628f5bf9d74 to your computer and use it in GitHub Desktop.
Save zhangchunlin/05576572b628f5bf9d74 to your computer and use it in GitHub Desktop.
prun, a little tool to run cmds parallel.
#! /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()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment