2010-05-07 4 views
0

Je souhaite exécuter une commande à l'aide de ssh.
J'utilise le SharpSSH library, comme dans cet exemple:Exécution d'une commande qui ne produit aucune sortie avec 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); 
    } 
} 

Mon problème est que lorsque la commande je lance ne produit aucune sortie, je reçois -1 code de retour, au lieu du code renvoyé par la commande sur la machine distante.
Est-ce que quelqu'un a rencontré ce problème ou est-ce que je fais quelque chose de mal?

+0

Avez-vous essayé d'utiliser la surcharge pour RunCommand et en ignorant simplement stdOut et stdErr et en lisant le code de retour retourné? Je suppose que cela ne semble pas être une grande différence. – kamranicus

Répondre

0

Si vous regardez réellement le code, getExitStatus n'est pas en fait le statut de sortie de la commande que vous avez exécutée, c'est l'état de sortie du "Channel" qui vient d'être créé pour exécuter votre commande. Ci-dessous est le seul endroit dans la totalité de la base de code où il est effectivement mis:

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;" est le code en question. Et, comme vous pouvez le voir, il est seulement mis sur un canal ouvert échouer. Sinon, ce sera la valeur par défaut de -1. J'imagine que Tamir avait l'intention de l'utiliser un peu plus largement, mais ne l'a jamais fait.

Dans les deux cas, il n'a jamais été conçu pour le but pour lequel vous l'utilisez.

Si vous vous connectez à une machine à base de Linux la seule façon, avec cette bibliothèque, pour obtenir le code de retour de commande est de mettre fin à votre appel de commande avec « echo $? », Donc vous voulez utiliser

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

Et puis analyser la déclaration pour ce code de commande à la fin. Peut-être même préfixer avec quelque chose facile à analyser, c'est-à-dire echo "RETURNCODE" $?

+0

Merci pour votre réponse et l'écho $? suggestion, mais en fait, si la commande que j'exécute produit une sortie, l'état de sortie ** est ** le code de retour de la commande ... –

2

Bien que ce soit une réponse très tard ... cela peut être utile pour les références futhure ...

Pour obtenir le code de retour du script exécuté, nous pouvons utiliser la valeur de retour de RunCommand lui-même.

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

Mais cela retournera 0 lorsqu'il n'y a pas de code retour à la sortie.

Questions connexes