-
Notifications
You must be signed in to change notification settings - Fork 1
/
shell.py
69 lines (52 loc) · 2.01 KB
/
shell.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from subprocess import Popen as popen
import re
import inspect
def run(script,var=None,show=False,run=True,wait=True,check=True):
'''
run script using variables
'''
if var == None:
#get local variables from calling function
_var = inspect.currentframe().f_back.f_locals
#filter to allow access only to basic variable types
var = {}
allowed = [str,int,float]
for k,v in _var.iteritems():
if type(v) in allowed:
var[k] = v
procs = []
if check:
#check that all variables can be assigned
for cmd in script.split('\n'):
if cmd.strip() == '': continue #blank line
#look for variable place holders in command
while True:
res = re.search(r'\[([a-zA-Z0-9_]+)\]',cmd)
if not res: break #no more place holders found
key = res.group(1)
#check a value is present for this variable
assert key in var
#remove the placeholder
cmd = cmd.replace('[%s]'%key,'')
for cmd in script.split('\n'):
if cmd.strip() == '': continue #blank line
#substitute parameter values
for key,val in var.iteritems():
_key = '[%s]'%key
if not _key in cmd: continue
cmd = cmd.replace(_key,str(val))
#decide if this command should block
block = True
if cmd.endswith('&'):
block = False
cmd = cmd[:-1]
#print command
if show: print cmd
if run:
p = popen(cmd,shell=True)
if block: p.wait() #wait for this step to complete
else: procs.append(p) #do not wait for this step to complete yet
#wait for all running processes to complete
if wait:
for p in procs:
p.wait()