Net/ssh question


#1

Those are my very first steps in Ruby. I wrote a small ruby program
which sends messages to client desktops in the same local network.
Basically, I ssh to each machine and execute a call to zenity to bring
up a GTK dialog with a custom message. Everything works fine, which was
unexpected by itself :-). The important piece of code here is:

Net::SSH.start( host,‘root’,rootpwd ) do |session|
session.open_channel do |channel|
channel.on_success do
#some unimportant things here
channel.send_data “zenity --title ‘IMPORTANT’ --info
–text ‘#{msg}’ &\n”
channel.close
end
channel.send_request “shell”, nil, true
end
session.loop
end

Now, to the question. By default some zenity options allow user input
which is directly sent to stdout. E.g. (directly copied from man page)

  • zenity --title “Select Host” --entry --text “Select the host you
    would like to flood-ping”

How can I capture the user input in this case? I tried unsuccessfully
to find something in the net/ssh documentation but I am lost in the
rdoc.

And one more question. As you noticed I run zenity in the background.
This is because if the user does not respod to the message (clicks OL,
etc…) zenity (and the ruby scirpt) just hangs and waits. Can I set a
timeout from within Ruby and close the channel after the timeout
expires? Of course I can always do it in bash:

expect -c "set timeout 30; eval spawn -noecho zenity … ; expect

but I would really prefer to do it from Ruby. In this way I can
distinguish a real timeout from a user action which did not result in
anything sent to stdout.

Thanks in advance.


#2

I solved my problems. I hadn’t paid attention to the
Net::SSH::Service::Shell module which allows me to do almost exactly
what I want. I still need to distinguish a timeout from a user action
which did not result in anything sent to stdout. Maybe I’ll just use
the SyncShell service, encapsulate a shell in a thread and have another
thread watch what’s going on with the first one. But I don’t know if
this can be done in ruby.