2017-09-15 2 views
0

Je tente d'exécuter quatre commandes sur un serveur distant en Java. Étant donné que les commandes impliquent des exportations, je les ai enchaîné en une seule commande:Java et SSH provoquant des blocages

rm -f nohup.out && export <a few similar commands> && nohup #here I execute a 
startup script#>nohup.out >nohup.out 2>nohup.err </dev/null & 

Je veux donc attendre un peu (environ 30 secondes) et analyser une adresse IP à partir nohup.out. Le problème que j'ai est que le programme se bloque et ne semble pas casser la connexion - le code de débogage indique qu'il casse quelque part dans le bloc de code ci-dessous, puisqu'il exécute effectivement la commande côté serveur avec succès

Comment puis-je fermer la connexion avec succès?

Le code d'envoi, qui utilise JSch et provient d'une solution mise à jour sur ce site, est le suivant. Il y a une ligne de débogage après celle-ci qui n'est jamais atteinte.

((ChannelExec)channel).setCommand(command); 
    InputStream commandOutput = channel.getInputStream(); 
    channel.connect(); 
    int readByte = commandOutput.read(); 

    while(readByte != 0xffffffff) 
    //while (true) 
    { 
     outputBuffer.append((char)readByte); 
     readByte = commandOutput.read(); 
    } 
+0

Que devez-vous le '' nohup' et & 'pour? –

+0

Le script côté serveur que j'exécute crache beaucoup de choses, ce dont je ne me soucie pas - je me soucie seulement d'une ligne qui contient une adresse IP. Franchement, je ne sais pas grand-chose sur ssh, donc potentiellement je n'ai pas besoin du nohup du tout. Mon idée était que cela supprimerait la sortie, et permettrait au programme Java de s'arrêter sans tuer le programme côté serveur. Ai-je tort de l'utiliser? –

+0

L'autre option que je peux envisager sans nohup serait de surveiller en continu la sortie du serveur jusqu'à ce que l'adresse IP apparaisse –

Répondre

0

J'ai eu des problèmes similaires, avec d'autres types de flux que je lisais (par exemple, les websockets). La plupart du temps, il s'agit de bloquer (read) et de ne pas réagir à l'interruption. Si tel est le cas, vous devrez peut-être forcer la fermeture du canal ou du swith pour ne pas bloquer (peut-être en utilisant available() ou quelque chose comme ça).

Encore mieux au lieu de faire des lectures d'interrogation, vous pouvez simplement spécifier le flux de sortie que vous voulez.

Voici un exemple de travail:

 executor = (ChannelExec) session.openChannel("exec"); 
     executor.setPty(true); 
     executor.setCommand(script); 
     executor.setOutputStream(output); 
     executor.setErrStream(error); 
     executor.connect(); 
     int errorStatus = -1; 

     for (int i = 0; !executor.isClosed(); i++) { 
      if (i > 0) { 
       long delayMs = (long) (200L * Math.pow(i, 2)); 
       Thread.sleep(delayMs); 
      } 
      if ((errorStatus = executor.getExitStatus()) != -1) { 
       break; 
      } 
     } 
     LOGGER.debug("Output: {}", output.toString()); 
     LOGGER.debug("Error: {}", error.toString()); 
+0

Ici, les flux de sortie et d'erreur sont les flux de lecture que je voudrais? –

+0

Oui, la seule différence est qu'avec votre approche vous lisez à votre rythme/interrogation tandis qu'avec le code suggéré la sortie sera écrite dans le tampon. – iocanel