def open_shell(command=None): """ Invoke a fully interactive shell on the remote end. If ``command`` is given, it will be sent down the pipe before handing control over to the invoking user. This function is most useful for when you need to interact with a heavily shell-based command or series of commands, such as when debugging or when fully interactive recovery is required upon remote program failure. It should be considered an easy way to work an interactive shell session into the middle of a Fabric script and is *not* a drop-in replacement for `~fabric.operations.run`, which is also capable of interacting with the remote end (albeit only while its given command is executing) and has much stronger programmatic abilities such as error handling and stdout/stderr capture. Specifically, `~fabric.operations.open_shell` provides a better interactive experience than `~fabric.operations.run`, but use of a full remote shell prevents Fabric from determining whether programs run within the shell have failed, and pollutes the stdout/stderr stream with shell output such as login banners, prompts and echoed stdin. Thus, this function does not have a return value and will not trigger Fabric's failure handling if any remote programs result in errors. .. versionadded:: 1.0 """ _execute(default_channel(), command, True, True, True)
def _run_command( command, shell=True, pty=True, combine_stderr=True, sudo=False, user=None, dir=None, format=Blank ): """ Underpinnings of `run` and `sudo`. See their docstrings for more info. """ if format is Blank: format = env.format if format: command = command.format(**env) if sudo and user: user = user.format(**env) # Set up new var so original argument can be displayed verbatim later. given_command = command # Handle context manager modifications, and shell wrapping wrapped_command = _shell_wrap( _prefix_env_vars(_prefix_commands(command, dir)), shell, _sudo_prefix(user) if sudo else None ) # Execute info line which = 'sudo' if sudo else 'run' prefix = "[%s]" % env.host_string if env.colors: prefix = env.color_settings['host_prefix'](prefix) if output.debug: print("%s %s: %s" % (prefix, which, wrapped_command)) elif output.running: print("%s %s: %s" % (prefix, which, given_command)) # Actual execution, stdin/stdout/stderr handling, and termination stdout, stderr, status = _execute(default_channel(), wrapped_command, pty, combine_stderr) # Assemble output string out = _AttributeString(stdout) err = _AttributeString(stderr) # Error handling out.failed = False if status != 0: out.failed = True msg = "%s() encountered an error (return code %s) while executing '%s'" % (which, status, command) _handle_failure(message=msg) # Attach return code to output string so users who have set things to # warn only, can inspect the error code. out.return_code = status # Convenience mirror of .failed out.succeeded = not out.failed # Attach stderr for anyone interested in that. out.stderr = err return out
def _run_command( command, shell=True, pty=True, combine_stderr=True, sudo=False, user=None, dir=None, format=Blank ): """ Underpinnings of `run` and `sudo`. See their docstrings for more info. """ if format is Blank: format = env.format if format: command = command.format(**env) # Set up new var so original argument can be displayed verbatim later. given_command = command # Handle context manager modifications, and shell wrapping wrapped_command = _shell_wrap( _prefix_env_vars(_prefix_commands(command, dir)), shell, _sudo_prefix(user) if sudo else None ) # Execute info line which = 'sudo' if sudo else 'run' prefix = "[%s]" % env.host_string if env.colors: prefix = env.color_settings['host_prefix'](prefix) if output.debug: print("%s %s: %s" % (prefix, which, wrapped_command)) elif output.running: print("%s %s: %s" % (prefix, which, given_command)) # Actual execution, stdin/stdout/stderr handling, and termination stdout, stderr, status = _execute(default_channel(), wrapped_command, pty, combine_stderr) # Assemble output string out = _AttributeString(stdout) err = _AttributeString(stderr) # Error handling out.failed = False if status != 0: out.failed = True msg = "%s() encountered an error (return code %s) while executing '%s'" % (which, status, command) _handle_failure(message=msg) # Attach return code to output string so users who have set things to # warn only, can inspect the error code. out.return_code = status # Convenience mirror of .failed out.succeeded = not out.failed # Attach stderr for anyone interested in that. out.stderr = err return out