Internal workhorse for exec_command().
(command, use_shell=None, use_tee = None, **env)
| 263 | |
| 264 | |
| 265 | def _exec_command(command, use_shell=None, use_tee = None, **env): |
| 266 | """ |
| 267 | Internal workhorse for exec_command(). |
| 268 | """ |
| 269 | if use_shell is None: |
| 270 | use_shell = os.name=='posix' |
| 271 | if use_tee is None: |
| 272 | use_tee = os.name=='posix' |
| 273 | |
| 274 | if os.name == 'posix' and use_shell: |
| 275 | # On POSIX, subprocess always uses /bin/sh, override |
| 276 | sh = os.environ.get('SHELL', '/bin/sh') |
| 277 | if is_sequence(command): |
| 278 | command = [sh, '-c', ' '.join(command)] |
| 279 | else: |
| 280 | command = [sh, '-c', command] |
| 281 | use_shell = False |
| 282 | |
| 283 | elif os.name == 'nt' and is_sequence(command): |
| 284 | # On Windows, join the string for CreateProcess() ourselves as |
| 285 | # subprocess does it a bit differently |
| 286 | command = ' '.join(_quote_arg(arg) for arg in command) |
| 287 | |
| 288 | # Inherit environment by default |
| 289 | env = env or None |
| 290 | try: |
| 291 | # universal_newlines is set to False so that communicate() |
| 292 | # will return bytes. We need to decode the output ourselves |
| 293 | # so that Python will not raise a UnicodeDecodeError when |
| 294 | # it encounters an invalid character; rather, we simply replace it |
| 295 | proc = subprocess.Popen(command, shell=use_shell, env=env, |
| 296 | stdout=subprocess.PIPE, |
| 297 | stderr=subprocess.STDOUT, |
| 298 | universal_newlines=False) |
| 299 | except EnvironmentError: |
| 300 | # Return 127, as os.spawn*() and /bin/sh do |
| 301 | return 127, '' |
| 302 | |
| 303 | text, err = proc.communicate() |
| 304 | mylocale = locale.getpreferredencoding(False) |
| 305 | if mylocale is None: |
| 306 | mylocale = 'ascii' |
| 307 | text = text.decode(mylocale, errors='replace') |
| 308 | text = text.replace('\r\n', '\n') |
| 309 | # Another historical oddity |
| 310 | if text[-1:] == '\n': |
| 311 | text = text[:-1] |
| 312 | |
| 313 | # stdio uses bytes in python 2, so to avoid issues, we simply |
| 314 | # remove all non-ascii characters |
| 315 | if sys.version_info < (3, 0): |
| 316 | text = text.encode('ascii', errors='replace') |
| 317 | |
| 318 | if use_tee and text: |
| 319 | print(text) |
| 320 | return proc.returncode, text |
| 321 | |
| 322 |
no test coverage detected