Выполнение команды, которая не выводит результат с помощью SharpSSH

Я хочу запустить команду, используя ssh.
Я использую библиотеку SharpSSH, как в этот пример:

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);
    }
}

Моя проблема в том, что когда команда, которую я запускаю, не выводит ничего, я получаю -1 в качестве кода возврата вместо кода, возвращаемого командой на удаленной машине.
Кто-нибудь сталкивался с этой проблемой или я делаю что-то не так?


person Paolo Tedesco    schedule 07.05.2010    source источник
comment
Вы пытались использовать перегрузку для RunCommand и просто игнорировать stdOut и stdErr и читать возвращенный код выхода? Я думаю, что это не похоже на большую разницу.   -  person kamranicus    schedule 20.01.2011


Ответы (2)


Хотя это очень поздний ответ... это может быть полезно для будущих ссылок...

Для получения кода возврата из исполняемого скрипта мы можем использовать возвращаемое значение самого RunCommand.

int returnCode = exec.RunCommand(strScript2, ref stdOut, ref stdError);

Но это вернет 0, если при выходе нет кода возврата.

person Priya Kathiresan    schedule 16.12.2011

Если вы на самом деле посмотрите на код, getExitStatus на самом деле не является статусом выхода команды, которую вы запустили, это статус выхода «Канала», который был только что создан для запуска вашей команды. Ниже приведено единственное место во всей кодовой базе, где он фактически установлен:

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=код_причины;" это код, о котором идет речь. И, как вы можете видеть, он устанавливается только при сбое открытия канала. В противном случае это будет значение по умолчанию -1.

Я предполагаю, что Тамир намеревался использовать это немного шире, но так и не сделал этого.

В любом случае, он никогда не предназначался для той цели, для которой вы пытаетесь его использовать.

Если вы подключаетесь к машине на базе Linux, единственный способ с помощью этой библиотеки получить код возврата команды — это завершить вызов команды с помощью «echo $?», поэтому вы хотели бы использовать

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

А затем проанализируйте возврат для этого кода команды в конце. Может быть, даже поставить перед ним что-то, что легко разобрать, например, echo "RETURNCODE"$?

person Adam Haile    schedule 29.06.2010
comment
Спасибо за ваш ответ и "echo $?" предложение, но на самом деле, если команда, которую я запускаю, выдает вывод, тогда статус выхода является кодом возврата команды... - person Paolo Tedesco; 30.06.2010