Revision 36117c2b lib/utils.py
b/lib/utils.py | ||
---|---|---|
103 | 103 |
output = property(_GetOutput, None, None, "Return full output") |
104 | 104 |
|
105 | 105 |
|
106 |
def RunCmd(cmd, env=None): |
|
106 |
def RunCmd(cmd, env=None, output=None):
|
|
107 | 107 |
"""Execute a (shell) command. |
108 | 108 |
|
109 | 109 |
The command should not read from its standard input, as it will be |
110 | 110 |
closed. |
111 | 111 |
|
112 |
@param cmd: Command to run |
|
113 | 112 |
@type cmd: string or list |
114 |
@param env: Additional environment
|
|
113 |
@param cmd: Command to run
|
|
115 | 114 |
@type env: dict |
115 |
@keyword env: Additional environment |
|
116 |
@type output: str |
|
117 |
@keyword output: if desired, the output of the command can be |
|
118 |
saved in a file instead of the RunResult instance; this |
|
119 |
parameter denotes the file name (if not None) |
|
120 |
@rtype: L{RunResult} |
|
116 | 121 |
@return: `RunResult` instance |
117 |
@rtype: RunResult |
|
118 | 122 |
|
119 | 123 |
""" |
120 | 124 |
if no_fork: |
... | ... | |
134 | 138 |
if env is not None: |
135 | 139 |
cmd_env.update(env) |
136 | 140 |
|
141 |
if output is None: |
|
142 |
out, err, status = _RunCmdPipe(cmd, cmd_env, shell) |
|
143 |
else: |
|
144 |
status = _RunCmdFile(cmd, cmd_env, shell, output) |
|
145 |
out = err = "" |
|
146 |
|
|
147 |
if status >= 0: |
|
148 |
exitcode = status |
|
149 |
signal_ = None |
|
150 |
else: |
|
151 |
exitcode = None |
|
152 |
signal_ = -status |
|
153 |
|
|
154 |
return RunResult(exitcode, signal_, out, err, strcmd) |
|
155 |
|
|
156 |
def _RunCmdPipe(cmd, env, via_shell): |
|
157 |
"""Run a command and return its output. |
|
158 |
|
|
159 |
@type cmd: string or list |
|
160 |
@param cmd: Command to run |
|
161 |
@type env: dict |
|
162 |
@param env: The environment to use |
|
163 |
@type via_shell: bool |
|
164 |
@param via_shell: if we should run via the shell |
|
165 |
@rtype: tuple |
|
166 |
@return: (out, err, status) |
|
167 |
|
|
168 |
""" |
|
137 | 169 |
poller = select.poll() |
138 |
child = subprocess.Popen(cmd, shell=shell, |
|
170 |
child = subprocess.Popen(cmd, shell=via_shell,
|
|
139 | 171 |
stderr=subprocess.PIPE, |
140 | 172 |
stdout=subprocess.PIPE, |
141 | 173 |
stdin=subprocess.PIPE, |
142 |
close_fds=True, env=cmd_env)
|
|
174 |
close_fds=True, env=env) |
|
143 | 175 |
|
144 | 176 |
child.stdin.close() |
145 | 177 |
poller.register(child.stdout, select.POLLIN) |
... | ... | |
173 | 205 |
err = err.getvalue() |
174 | 206 |
|
175 | 207 |
status = child.wait() |
176 |
if status >= 0: |
|
177 |
exitcode = status |
|
178 |
signal_ = None |
|
179 |
else: |
|
180 |
exitcode = None |
|
181 |
signal_ = -status |
|
208 |
return out, err, status |
|
182 | 209 |
|
183 |
return RunResult(exitcode, signal_, out, err, strcmd) |
|
210 |
|
|
211 |
def _RunCmdFile(cmd, env, via_shell, output): |
|
212 |
"""Run a command and save its output to a file. |
|
213 |
|
|
214 |
@type cmd: string or list |
|
215 |
@param cmd: Command to run |
|
216 |
@type env: dict |
|
217 |
@param env: The environment to use |
|
218 |
@type via_shell: bool |
|
219 |
@param via_shell: if we should run via the shell |
|
220 |
@type output: str |
|
221 |
@param output: the filename in which to save the output |
|
222 |
@rtype: int |
|
223 |
@return: the exit status |
|
224 |
|
|
225 |
""" |
|
226 |
fh = open(output, "a") |
|
227 |
try: |
|
228 |
child = subprocess.Popen(cmd, shell=via_shell, |
|
229 |
stderr=subprocess.STDOUT, |
|
230 |
stdout=fh, |
|
231 |
stdin=subprocess.PIPE, |
|
232 |
close_fds=True, env=env) |
|
233 |
|
|
234 |
child.stdin.close() |
|
235 |
status = child.wait() |
|
236 |
finally: |
|
237 |
fh.close() |
|
238 |
return status |
|
184 | 239 |
|
185 | 240 |
|
186 | 241 |
def RemoveFile(filename): |
Also available in: Unified diff