From: Brian Candler Date: 2008-09-08T22:05:10+09:00 Subject: Re: Telnet client > I use ruby wrote a Telnet client application. It works fine until users > want to change a user name or telnet to other host. I found all these > failed operations are related with "su -" command or login. How can I > let ruby deal with these? Below is my core code for this telnet client: > > while 1 == 1 > c=gets > tn.cmd(c){|c| print c} > if c=="exit" > break > end > end > > It simply get what user input and put it on the telnet server. I am having to guess here, but I imagine that tn is an instance of a Net::Telnet object? You haven't described exactly what your problem is. In what way do your "failed operations" fail? What exactly do the users type, what do they see in response, and what do you expect them to see? I can see a few problems with the above code though. * 'gets' receives a whole line at a time. If you try to use an interactive program like vi, it will fail. If that's not what you want, have a look at Curses, HighLine, or ruby-termios. http://codeidol.com/other/rubyckbk/User-Interface/Getting-Input-One-Character-at-a-Time/ * In the third line above, under ruby 1.8 the block parameter 'c' is bound to the same variable as the 'c' outside. This means that the value of 'c' will have changed after the block has executed. This means that if c was equal to 'exit' before, it may not be equal afterwards if the block has been invoked one or more times. * c will never equal "exit" because you are reading whole lines with their terminator. It will be "exit\n". So a cleaned-up version of your code might be: loop do c = gets tn.cmd(c) { |resp| print resp } break if c == "exit\n" end Having said that, it would be better to detect if the far end drops the connection rather than seeing if the user typed "exit". The user could legitimately type "exit" for reasons other than logging out; and they could logout by typing "logout". I'm not sure the best way to do that with Net::Telnet. If you're waiting for a specific response then you can test whether the value returned from 'cmd' matches the string you were expecting. Otherwise, you can try sending data and rescuing the Errno::EPIPE you get if the other end has closed. I'd say that Net::Telnet is really designed for scripting telnet sessions, not for writing your own interactive telnet client. HTH, Brian.