>From: CN=Ville Mattila/O=Stone
>Date: 09/04/2004 11:27:02
>Subject: Re: [Net-ssh-devel] Simple question
>
>>
>>You can use the "Net::SSH::Service::Process.popen3" method to
start a
>>synchronous "session" over a given connection. Something like
this:
>>
>>Net::SSH.start( host, login, password ) do |session|
>>input, output, error >>Net::SSH::Service::Process.popen3( session,
"sh" )
>>
>>input.puts "cd /var"
>>input.puts "pwd"
>>result = output.read
>>input.puts "exit"
>>
>>assert_equal "/var", result
>>end
>>
>>It''s not as visually pleasing as Telnet#cmd, but it should work
for now.
>>The problem is that the SSH protocol is much more complicated than
>>Telnet, running multiple channels in parallel. However, given the popen3
>>functionality, it should be possible to further abstract that away to
>>get something closer to the Telnet#cmd interface.
>>
>>Hope that helps,
>
> Yes, this helps a lot. I''ll try do implement cmd abstarction on
the
top of>the popen3.
> If its good enough, I''ll send a patch. Thanks for help!
Hello again,
I''ve now cooked up the solution solution below and it does about
what I
need. Note that this
is work in progess so the interpreter thread is not terminated and so
on...
There is one problem still . If I''m giving command that does not
generate
output
the thing blocks for exaple expect("cd /var", ""). The
reason is that
SSHStdoutPipe#bytes_available
does not work as expected it always returns 0. I tried to fix this myself
but got lost.
def expect(command, expected_output, &block)
@cmd_output = nil
if @expect_thread == nil
@next_command_condition_variable = ConditionVariable.new
@next_command_mutex = Mutex.new
@expect_thread = Thread.new do
$stdout.sync = true
@next_command_mutex.synchronize do
@connection.open(@login, @password) do |session|
input, output, error
Net::SSH::Service::Process.popen3(session, "bash")
while true
puts("waiting for command")
@next_command_condition_variable.wait(@next_command_mutex)
puts("processing #{@command_input}")
input.puts(@command_input)
puts("Thr getting output: " +
output.bytes_available.to_s)
#if output.bytes_available > 0 << Cannot use because
always 0
@cmd_output = output.read
#end
puts("Thr got: #{@cmd_output} : " +
output.bytes_available.to_s)
@next_command_condition_variable.signal
end
end
end
end
end
if @expect_thread and not @expect_thread.alive?
@expect_thread.join
end
a = Thread.new do
@next_command_mutex.synchronize do
@command_input = command
@next_command_condition_variable.signal
@next_command_condition_variable.wait(@next_command_mutex)
end
end
a.join
puts("Main Thr got: #{@cmd_output}")
@cmd_output
end