[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

How can I get command's result code, which executing via ssh

Ivan Samonov

6/1/2009 10:09:00 AM

I use net/ssh library.
My code:
require 'rubygems'
require 'net/ssh'
Net::SSH.start('server', 'login') { |ssh| ssh.open_channel { |ch|
ch.exec('false') { |ch, success| puts success } } }
"false" is a console program and it always return 1.
Why result of this program is "true"? What mean "success" here? I think
I misunderstand something.
--
Posted via http://www.ruby-....

8 Answers

Robert Klemme

6/1/2009 12:20:00 PM

0

On 01.06.2009 12:09, Ivan Samonov wrote:
> I use net/ssh library.
> My code:
> require 'rubygems'
> require 'net/ssh'
> Net::SSH.start('server', 'login') { |ssh| ssh.open_channel { |ch|
> ch.exec('false') { |ch, success| puts success } } }
> "false" is a console program and it always return 1.
> Why result of this program is "true"? What mean "success" here? I think
> I misunderstand something.

This is likely because SSH does not propagate the result of the remote
process. You can find the details on SSH's manpage.

One way would be to send something like

echo "$?"

as last command and read this.

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestprac...

Brian Candler

6/1/2009 12:48:00 PM

0

Robert Klemme wrote:
> This is likely because SSH does not propagate the result of the remote
> process. You can find the details on SSH's manpage.

Ahem??

'man ssh' on my system (Ubuntu Hardy) says:

ssh exits with the exit status of the remote command or with 255 if
an
error occurred.

A quick test confirms this to be true. So clearly the exit status *is*
propagated back. More likely it's just a problem with the OP's use of
the Net::SSH API.

Now, the Net::SSH API documentation (*) for exec tells you:

"success means that the command is being executed, not that it has
completed"

And if it hasn't completed, obviously you can't get the exit status. I
admit the documentation doesn't make it easy to see at a glance how you
*should* get the exit status.

But in any case, I think it's not helpful to post unverified guesses
about the behaviour of such a system.

Regards,

Brian.

(*) http://net-ssh.rubyforge.org/ssh/v2/api/...
--
Posted via http://www.ruby-....

Brian Candler

6/1/2009 1:00:00 PM

0

A quick check of the SSH protocol spec in RFC 4254 says, in section
6.10:

When the command running at the other end terminates, the following
message can be sent to return the exit status of the command.
Returning the status is RECOMMENDED. No acknowledgement is sent for
this message. The channel needs to be closed with
SSH_MSG_CHANNEL_CLOSE after this message.

The client MAY ignore these messages.

byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "exit-status"
boolean FALSE
uint32 exit_status

(and it then goes on to describe the "exit-signal" message as well)

Grepping for exit-status in the net-ssh source turns up an example of
how to get it:

# * "exit-status" : the exit status of the remote process will be
reported
# as a long integer in the data buffer, which you can grab via
# data.read_long.
# * "exit-signal" : if the remote process died as a result of a
signal
# being sent to it, the signal will be reported as a string in the
# data, via data.read_string. (Not all SSH servers support this
channel
# request type.)
#
# channel.on_request "exit-status" do |ch, data|
# puts "process terminated with exit status: #{data.read_long}"
# end
--
Posted via http://www.ruby-....

Brian Candler

6/1/2009 1:10:00 PM

0

One other point. It's very dangerous to do

ch.foo { |ch| ... }

because (in ruby 1.8) 'ch' is bound to the same variable in both cases.
That is, the value assigned to the block parameter also changes the
outer 'ch'. So you should call them something different.

The finished program becomes:

require 'rubygems'
require 'net/ssh'
Net::SSH.start('localhost', 'yourname') { |ssh|
ssh.open_channel { |chan|
chan.on_request('exit-status') { |ch, data|
puts "process terminated with exit status: #{data.read_long}"
}
chan.exec('false') { |ch, success| puts success }
}
}
--
Posted via http://www.ruby-....

Aaron Turner

6/1/2009 5:13:00 PM

0

On Mon, Jun 1, 2009 at 3:09 AM, Ivan Samonov <hronya@gmail.com> wrote:
> I use net/ssh library.
> My code:
> require 'rubygems'
> require 'net/ssh'
> Net::SSH.start('server', 'login') { |ssh| ssh.open_channel { |ch|
> ch.exec('false') { |ch, success| puts success } =A0} }
> "false" is a console program and it always return 1.
> Why result of this program is "true"? =A0What mean "success" here? I thin=
k
> I misunderstand something.

I just ran into the same problem last week and I ended up doing what
Robert suggested:

retcode =3D ch.exec('my_command >/dev/null 2>&1 ; echo $?')

you can also do things like is:
results =3D ch.exec('my_command && echo SUCCESS || echo FAILURE')

--=20
Aaron Turner
http://s...
http://tcpreplay.s... - Pcap editing and replay tools for Unix & Win=
dows
Those who would give up essential Liberty, to purchase a little temporary
Safety, deserve neither Liberty nor Safety.
-- Benjamin Franklin

Robert Klemme

6/1/2009 8:25:00 PM

0

On 01.06.2009 14:48, Brian Candler wrote:

> But in any case, I think it's not helpful to post unverified guesses
> about the behaviour of such a system.

I am pretty sure that the ssh on at least one system we have at work
does not return the remote command's exit status. This is not a guess
but I cannot verify it at the moment now because I do not have access to
the system right now.

robert


--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestprac...

Brian Candler

6/1/2009 8:49:00 PM

0

Robert Klemme wrote:
> On 01.06.2009 14:48, Brian Candler wrote:
>
>> But in any case, I think it's not helpful to post unverified guesses
>> about the behaviour of such a system.
>
> I am pretty sure that the ssh on at least one system we have at work
> does not return the remote command's exit status. This is not a guess
> but I cannot verify it at the moment now because I do not have access to
> the system right now.

You said: "SSH does not propagate the result of the remote process. You
can find the details on SSH's manpage", but a check of the manpage says
otherwise.

Of course, perhaps older versions of ssh are different. However the
system I checked on was Ubuntu Hardy, which isn't exactly bleeding edge.
--
Posted via http://www.ruby-....

Ivan Samonov

6/1/2009 8:58:00 PM

0

Brian Candler wrote:
> One other point. It's very dangerous to do
>
> ch.foo { |ch| ... }
>
> because (in ruby 1.8) 'ch' is bound to the same variable in both cases.
> That is, the value assigned to the block parameter also changes the
> outer 'ch'. So you should call them something different.
>

We use 1.9

> The finished program becomes:
>
> require 'rubygems'
> require 'net/ssh'
> Net::SSH.start('localhost', 'yourname') { |ssh|
> ssh.open_channel { |chan|
> chan.on_request('exit-status') { |ch, data|
> puts "process terminated with exit status: #{data.read_long}"
> }
> chan.exec('false') { |ch, success| puts success }
> }
> }

Thanks! It's what I need!
--
Posted via http://www.ruby-....