예제 #1
0
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)
예제 #2
0
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)
예제 #3
0
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
예제 #4
0
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