Internal workhorse for exec_command().
(command, use_shell=None, use_tee = None, **env)
| 251 | |
| 252 | |
| 253 | def _exec_command(command, use_shell=None, use_tee = None, **env): |
| 254 | """ |
| 255 | Internal workhorse for exec_command(). |
| 256 | """ |
| 257 | if use_shell is None: |
| 258 | use_shell = os.name=='posix' |
| 259 | if use_tee is None: |
| 260 | use_tee = os.name=='posix' |
| 261 | |
| 262 | if os.name == 'posix' and use_shell: |
| 263 | # On POSIX, subprocess always uses /bin/sh, override |
| 264 | sh = os.environ.get('SHELL', '/bin/sh') |
| 265 | if is_sequence(command): |
| 266 | command = [sh, '-c', ' '.join(command)] |
| 267 | else: |
| 268 | command = [sh, '-c', command] |
| 269 | use_shell = False |
| 270 | |
| 271 | elif os.name == 'nt' and is_sequence(command): |
| 272 | # On Windows, join the string for CreateProcess() ourselves as |
| 273 | # subprocess does it a bit differently |
| 274 | command = ' '.join(_quote_arg(arg) for arg in command) |
| 275 | |
| 276 | # Inherit environment by default |
| 277 | env = env or None |
| 278 | try: |
| 279 | # text is set to False so that communicate() |
| 280 | # will return bytes. We need to decode the output ourselves |
| 281 | # so that Python will not raise a UnicodeDecodeError when |
| 282 | # it encounters an invalid character; rather, we simply replace it |
| 283 | proc = subprocess.Popen(command, shell=use_shell, env=env, text=False, |
| 284 | stdout=subprocess.PIPE, |
| 285 | stderr=subprocess.STDOUT) |
| 286 | except OSError: |
| 287 | # Return 127, as os.spawn*() and /bin/sh do |
| 288 | return 127, '' |
| 289 | |
| 290 | text, err = proc.communicate() |
| 291 | mylocale = locale.getpreferredencoding(False) |
| 292 | if mylocale is None: |
| 293 | mylocale = 'ascii' |
| 294 | text = text.decode(mylocale, errors='replace') |
| 295 | text = text.replace('\r\n', '\n') |
| 296 | # Another historical oddity |
| 297 | if text[-1:] == '\n': |
| 298 | text = text[:-1] |
| 299 | |
| 300 | if use_tee and text: |
| 301 | print(text) |
| 302 | return proc.returncode, text |
| 303 | |
| 304 | |
| 305 | def _quote_arg(arg): |
no test coverage detected