Bash – Use keyboard-interactive authentication when piping ssh output to other command

bashpipessh

I'd like to pipe the output of ssh to a different command. For example:

ssh myserver cat remote-file | diff local-file -

The problem is that myserver asks for a password, but I can't enter it. (For some reason, public-key authentication is not available on the server. I can't change this.) I get the "Password:" prompt, but the keys I type are echoed, and not passed to ssh. How can I make ssh get the password?

Note I'm not trying to pipe the password into ssh. I'm trying to pipe the output of ssh, and enter the password as usual.

In case it matters, I'm using bash on OS X 10.7 (Lion), and the standard Terminal. I have no aliases set up that could cause this. I've seen the same problem different (Linux) systems, so I believe it's not specific to my setup.

Best Answer

OK, it turns out this was due to a bizarre interaction with my bash configuration.

I have something in my .bash_profile that puts the currently executed command into the window title, or the screen tab. It works by using a trap:

trap 'bash_current_command' DEBUG

and before that:

function bash_current_command {
    # only works in bash > 3.1
    #set -- $BASH_COMMAND

    # for old bash
    set -- $(history 1)
    shift

    if [[ "$1" == "sudo" ]]; then
        cmd="*$(basename -- "$2")*"
    else
        cmd="$(basename -- "$1")"
    fi

    bash_set_title "$cmd"
}

bash_set_title is a little function that sets the current terminal's title and icon title using ANSI escape codes. As you can see, this creates subshells $(...), and my intuition told me this could be the problem. Indeed, after I changed those lines, it worked!

If someone knows why this happens, I'd be glad to hear details. Do subshells generally steal tty input? Or is it only a problem in a debug trap? I don't recall problems with regular stdin input / piping into commands.

(As you can also see, there are a few problems with my function anyway - it uses one of the subshells as a workaround so it can run on an archaic bash version (I'm stuck with it on a legacy system, but still wanted a unified configuration). The other subshell is used to extract the actual command when using sudo, but this fails if sudo is called with switches like sudo -H -u user command. So I'll regard this as an opportunity to fix up this code...)

Related Question