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