-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathBash.py
More file actions
173 lines (130 loc) · 4.25 KB
/
Bash.py
File metadata and controls
173 lines (130 loc) · 4.25 KB
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# This file defines the interface for bash-specific stuff
import sys
import re
from StringIO import StringIO
from EnvironmentObjects import EnvVariable, LocVariable, LocFunction, Alias, EWObjKey
from Debug import log
def EscapeSingleQuotes(line):
if len(line) >2 and line[0]=="'" and line[-1]=="'":
return line[1:-1].replace("'","'\\''")
else:
return line.replace("'","'\\''")
class BashEnvVariable(EnvVariable):
"""docstring for BashEnvVariable"""
_pattern = re.compile("""^(?P<name>[^= '"/\\\\]+?)=(?P<value>.*)\n?$""")
def DefineCode(self):
return "export %s=%s;" % (self._name,self._value)
def RemoveCode(self):
return "unset %s;\n" % self.name
class BashLocVariable(LocVariable):
"""docstring for BashLocVariable"""
_pattern = re.compile("""^(?P<name>[^= '"\\\\]+?)=(?P<value>.*)\n?$""")
def DefineCode(self):
return "%s=%s;" % (self._name, self._value)
def RemoveCode(self):
return "unset %s;\n" % self.name
class BashLocFunction(LocFunction):
"""docstring for BashLocFunction"""
_pattern = re.compile("""^(?P<name>[^= ]+) \(\) \n?$""")
def ParseBodyLine(self, line):
if self.value:
self.value += "\n"
self.value += line
return (line == "}") # when this is encountered, the function is closed, any loop should terminate here.
def DefineCode(self):
return "function %s %s" % (self._name, self._value)
def RemoveCode(self):
return "unset %s;\n" % self.name
class BashAlias(Alias):
"""docstring for BashAlias"""
_pattern = re.compile("""^alias (?P<name>[^=]+)=(?P<value>.*)\n?$""")
def DefineCode(self):
return "alias %s=%s;" % (self._name, self._value)
def RemoveCode(self):
return "unalias %s\n" % self.name
class BashInteractor(object):
"""Is able to read and write BASH code"""
_loc_tag = "ENV_WATCHER_LOCALS>>"
_ali_tag = "ENV_WATCHER_ALIAS>>"
_ignore_file = "bash_ignore.txt"
def __init__(self, conf_dir, input):
super(BashInteractor, self).__init__()
self.conf_dir = conf_dir
self.ignore = self.GetIgnoreList(self.conf_dir+"/"+self._ignore_file)
self.input = input
self.env_dict = None
@property
def environment(self):
if not self.env_dict:
self.env_dict = self.ParseAll(self.input)
return self.env_dict
def GetIgnoreList(self, filename):
ignore_file = open(filename).read().splitlines()
ignore_list=[]
for line in ignore_file:
line = line.strip()
# Take out comments
if not line or line[0] == "#":
continue
ignore_list.append(line)
return ignore_list
def ParseAll(self,text):
log("Now Parsing bash environment",text)
env_dict = {}
# first get the environment:
import os
for name,value in os.environ.iteritems():
# honor the ignore configuration
if name in self.ignore:
continue
obj = BashEnvVariable(name, value)
env_dict[obj.key()] = obj
# next parse the text that was passed on from the function.
intext = iter(text.splitlines())
for line in intext:
if not line:
continue
if line == self._loc_tag:
break
for line in intext:
if not line:
continue
if line == self._ali_tag:
break
# Now ready to parse local variables
# The locals can eiter be variables or functions
if BashLocVariable.Matches(line):
obj = BashLocVariable.Parse(line)
elif BashLocFunction.Matches(line):
obj = BashLocFunction.Parse(line)
for line in intext:
if obj.ParseBodyLine(line):
break
else:
print >>sys.stderr,"Warning: unknown bash environment line:\n\t=>"+line
log("unknown bash environment line:\n\t=>",line)
continue
#Bash inserts the environment variables into the local variables.
# I therefore want to make sure this wasn't an EnvVariable
if obj.name in os.environ:
continue
# honor the ignore configuration
if obj.name in self.ignore:
continue
env_dict[obj.key()] = obj
for line in intext:
if not line:
continue
# Now ready to parse alias
if not BashAlias.Matches(line):
log("Warning: unknown bash alias:\n\t=>",line)
print >>sys.stderr,"Warning: unknown bash alias:\n\t=>"+line
continue
obj = BashAlias.Parse(line)
# honor the ignore configuration
if obj.name in self.ignore:
continue
env_dict[obj.key()] = obj
# for k, v in env_dict.iteritems():
# print v.DefineCode()
return env_dict