Note: This function is based on paramiko's exec_command() method. :param timeout: How long to wait (in seconds) for the command to finish (optional). :type timeout: ``float`` :param call_line_handler_func: True to call handle_stdout_line_func function for e
(self, cmd, timeout=None, quote=False, call_line_handler_func=False)
| 377 | return self.sftp.rmdir(path) |
| 378 | |
| 379 | def run(self, cmd, timeout=None, quote=False, call_line_handler_func=False): |
| 380 | """ |
| 381 | Note: This function is based on paramiko's exec_command() |
| 382 | method. |
| 383 | |
| 384 | :param timeout: How long to wait (in seconds) for the command to finish (optional). |
| 385 | :type timeout: ``float`` |
| 386 | |
| 387 | :param call_line_handler_func: True to call handle_stdout_line_func function for each line |
| 388 | of received stdout and handle_stderr_line_func for each |
| 389 | line of stderr. |
| 390 | :type call_line_handler_func: ``bool`` |
| 391 | """ |
| 392 | |
| 393 | if quote: |
| 394 | cmd = quote_unix(cmd) |
| 395 | |
| 396 | extra = {"_cmd": cmd} |
| 397 | self.logger.info("Executing command", extra=extra) |
| 398 | |
| 399 | # Use the system default buffer size |
| 400 | bufsize = -1 |
| 401 | |
| 402 | transport = self.client.get_transport() |
| 403 | chan = transport.open_session() |
| 404 | |
| 405 | start_time = time.time() |
| 406 | if cmd.startswith("sudo"): |
| 407 | # Note that fabric does this as well. If you set pty, stdout and stderr |
| 408 | # streams will be combined into one. |
| 409 | # NOTE: If pty is used, every new line character \n will be converted to \r\n which |
| 410 | # isn't desired. Because of that we sanitize the output and replace \r\n with \n at the |
| 411 | # bottom of this method |
| 412 | uses_pty = True |
| 413 | chan.get_pty() |
| 414 | else: |
| 415 | uses_pty = False |
| 416 | chan.exec_command(cmd) |
| 417 | |
| 418 | stdout = StringIO() |
| 419 | stderr = StringIO() |
| 420 | |
| 421 | # Create a stdin file and immediately close it to prevent any |
| 422 | # interactive script from hanging the process. |
| 423 | stdin = chan.makefile("wb", bufsize) |
| 424 | stdin.close() |
| 425 | |
| 426 | # Receive all the output |
| 427 | # Note #1: This is used instead of chan.makefile approach to prevent |
| 428 | # buffering issues and hanging if the executed command produces a lot |
| 429 | # of output. |
| 430 | # |
| 431 | # Note #2: If you are going to remove "ready" checks inside the loop |
| 432 | # you are going to have a bad time. Trying to consume from a channel |
| 433 | # which is not ready will block for indefinitely. |
| 434 | exit_status_ready = chan.exit_status_ready() |
| 435 | |
| 436 | if exit_status_ready: |