views:

137

answers:

2

I wanted to automate ssh logins. After some research, it seemed like tcl/expect was the route to go.

However, my issue is that when interact takes over my terminal, stuff doesn't work as expected (pun not intended).

For example, if I resize the terminal, it does not "take". Also, sometimes the interact is not responsive, and sometimes it just hangs for no reason. I have included my code below. My question for the code is, am I missing something?

Also, is there a better way to do this (with another scripting language?) I need the terminal to be very responsive, and no different than if I had manually typed ssh on the console.

proc Login {username server password} {
    set prompt "(%|>|\#|\\\$) $"

    spawn /usr/bin/ssh $username@$server
    expect { 
        -re "Are you sure you want to continue connecting (yes/no)?" {
            exp_send "yes\r"
            exp_continue 
            #continue to match statements within this expect {}
        }

        -nocase "password: " { 
            exp_send "$password\r" 
            interact
        }
    }
}
A: 

As W. Craig Trader mentions in a comment, the "right" way to do this is to use ssh-keygen to generate a key for authentication.

You can avoid the "continue" prompt by setting -o StrictHostKeyChecking=no.

bstpierre
+1  A: 

The issue you bring up about 'interact' not noticing that the window has changed size is because, by default, interact only watches the streams of characters. When you resize the window, a WINCH signal is raised. By default, Expect has the, uh, default action which is to ignore it. You should use Expect's trap command to catch the SIGWINCH. Then you can do what you want - for example, propagating the new size to the other side or taking some other local action.

You can find examples in Expect's sample scripts that do this. And there is an explanation and example in the Expect book of how to handle SIGWINCH.

donlibes