tags:

views:

182

answers:

2

I want to run a command using ssh.
I am using the SharpSSH library, as in this example:

using System;
using Tamir.SharpSsh;

class Program {
    static void Main(string[] args) {
        string hostName = "host.foo.com";
        string userName = "user";
        string privateKeyFile = @"C:\privatekey.private";
        string privateKeyPassword = "xxx";

        SshExec sshExec = new SshExec(hostName, userName);
        sshExec.AddIdentityFile(privateKeyFile, privateKeyPassword);
        sshExec.Connect();
        string command = string.Join(" ", args);
        Console.WriteLine("command = {0}", command);
        string output = sshExec.RunCommand(command);

        int code = sshExec.ChannelExec.getExitStatus();
        sshExec.Close();
        Console.WriteLine("code = {0}", code);
        Console.WriteLine("output = {0}", output);
    }
}

My problem is that when the command I run produces no output, I get -1 as return code, instead of the code returned by the command on the remote machine.
Has someone encountered this problem, or am I doing something wrong?

A: 

Hi, I'm having the exact same problem. Did you solve it?

RunCommand
A: 

If you actually look at the code, getExitStatus is not actually the exit status of the command you ran, it's the exit status of the "Channel" that was just created to run your command. Below is the only place in the entire code base where it's actually set:

case SSH_MSG_CHANNEL_OPEN_FAILURE:
                            buf.getInt();
                            buf.getShort();
                            i=buf.getInt();
                            channel=Channel.getChannel(i, this);
                            if(channel==null)
                            {
                                //break;
                            }
                            int reason_code=buf.getInt();
                            //foo=buf.getString();  // additional textual information
                            //foo=buf.getString();  // language tag
                            channel.exitstatus=reason_code;
                            channel._close=true;
                            channel._eof_remote=true;
                            channel.setRecipient(0);
                            break;

"channel.exitstatus=reason_code;" is the code in question. And, as you can see it's only set on a Channel open fail. Otherwise, it will be it's default value of -1.

I imagine that Tamir intended to use this a little more extensively, but never did so.

Either way, it was never intended for the purpose you are trying to use it for.

If you are connecting to a linux based machine the only way, with this library, to get the command return code is to end your command call with "echo $?", so you would want to use

sshExec.RunCommand(command + ";echo $?");

And then parse the return for that command code at the end. Maybe even prefix it with something easy to parse for, i.e. echo "RETURNCODE"$?

Adam Haile
Thanks for your answer and the 'echo $?' suggestion, but actually if the command I run produces output then the exit status **is** the command return code...
Paolo Tedesco