Lecture du résultat de la commande JSch : résolution du blocage de sortie
Ce code se bloque systématiquement lors d'une tentative de lecture à partir de l'instance Reader :
JSch jsch = new JSch(); jsch.setKnownHosts(dotSshDir + "/known_hosts"); jsch.addIdentity(dotSshDir + "/id_rsa"); Session session = jsch.getSession(userName, hostname, 22); session.connect(); ChannelExec channel = (ChannelExec) session.openChannel("exec"); channel.setCommand(command); channel.setInputStream(null); channel.setErrStream(System.err); Reader reader = new InputStreamReader(channel.getInputStream()); char[] buf = new char[1024]; int numRead; while ((numRead = reader.read(buf)) != -1) { String readData = String.valueOf(buf, 0, numRead); result.append(readData); buf = new char[1024]; }
Cause première :
Le problème survient car le code ne lit pas la sortie en continu en attendant la fin de la commande. Lorsque la commande génère une sortie suffisante pour remplir le tampon de sortie, la commande s'arrête, en attendant la consommation du tampon. Cependant, cela ne se produit jamais, conduisant à une impasse.
Solution :
Pour résoudre ce problème, il est crucial de lire en continu les flux stdout et stderr pendant la surveillance. l'état de la commande :
ChannelExec channel = (ChannelExec)session.openChannel("exec"); channel.setCommand( "for((i=1;i<=10000;i+=2)); do echo \"Long output - $i\"; done ; " + "echo error output >&2"); ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream(); ByteArrayOutputStream errorBuffer = new ByteArrayOutputStream(); InputStream in = channel.getInputStream(); InputStream err = channel.getExtInputStream(); channel.connect(); byte[] tmp = new byte[1024]; while (true) { while (in.available() > 0) { int i = in.read(tmp, 0, 1024); if (i < 0) break; outputBuffer.write(tmp, 0, i); } while (err.available() > 0) { int i = err.read(tmp, 0, 1024); if (i < 0) break; errorBuffer.write(tmp, 0, i); } if (channel.isClosed()) { if ((in.available() > 0) || (err.available() > 0)) continue; System.out.println("exit-status: " + channel.getExitStatus()); break; } try { Thread.sleep(1000); } catch (Exception ee) { } } System.out.println("output: " + outputBuffer.toString("UTF-8")); System.out.println("error: " + errorBuffer.toString("UTF-8")); channel.disconnect();
Cette approche garantit que la sortie est lue en continu, évitant ainsi le blocage.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!