Múltiples comandos a través de Jsch Shell

Yo estaba tratando de ejecutar varios comandos a través del protocolo SSH utilizando la biblioteca JSch. Pero parece que me han pegado y no puedo encontrar ninguna solución. El método setCommand() sólo puede ejecutar comandos individuales por sesión. Pero quiero ejecutar los comandos secuencialmente como la aplicación connectbot en la plataforma Android. Hasta ahora mi código es:

 package com.example.ssh; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Properties; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import com.jcraft.jsch.Channel; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; public class ExampleSSH extends Activity { /** Called when the activity is first created. */ EditText command; TextView result; Session session; ByteArrayOutputStream baos; ByteArrayInputStream bais; Channel channel; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); bais = new ByteArrayInputStream(new byte[1000]); command = (EditText) findViewById(R.id.editText1); result = (TextView) findViewById(R.id.terminal); } public void onSSH(View v){ String username = "xxxyyyzzz"; String password = "aaabbbccc"; String host = "192.168.1.1"; // sample ip address if(command.getText().toString() != ""){ JSch jsch = new JSch(); try { session = jsch.getSession(username, host, 22); session.setPassword(password); Properties properties = new Properties(); properties.put("StrictHostKeyChecking", "no"); session.setConfig(properties); session.connect(30000); channel = session.openChannel("shell"); channel.setInputStream(bais); channel.setOutputStream(baos); channel.connect(); } catch (JSchException e) { // TODO Auto-generated catch block Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show(); } } else{ Toast.makeText(this, "Command cannot be empty !", Toast.LENGTH_LONG).show(); } } public void onCommand(View v){ try { bais.read(command.getText().toString().getBytes()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } baos = new ByteArrayOutputStream(); channel.setOutputStream(baos); result.setText(baos.toString()); } } 

El código parece conectarse al servidor, pero creo que hay algún problema con los búferes de matriz de entrada y salida, porque no hay salida en absoluto. ¿Puede alguien guiarnos por favor cómo manejar la entrada y la salida ay desde el servidor correctamente para conseguir la salida deseada?

Si no tiene que distinguir las entradas o salidas de los comandos individuales, la respuesta de Aaron (que da todos los comandos en una fila, separados por \n o ; ) está bien.

Si tiene que manejarlos por separado, o no sabe los comandos posteriores antes de que los anteriores estén terminados: Puede abrir varios canales de exec en la misma sesión (es decir, conexión), uno tras otro (es decir, después de la anterior era cerrado). Cada uno tiene su propio comando. (Pero no comparten el entorno, por lo que un comando cd en el primero no tiene ningún efecto sobre los posteriores.)

Sólo tiene que tener cuidado de tener el objeto Session alrededor, y no crear uno nuevo para cada comando.

Otra opción sería un canal de shell , y luego pasar los comandos individuales a la shell remota como entrada (es decir, a través de una secuencia). Pero entonces usted tiene que tener cuidado de no mezclar la entrada de un comando con el siguiente comando (es decir, esto sólo funciona si usted sabe lo que están haciendo los comandos, o si tiene un usuario interactivo que puede proporcionar tanto la entrada de la orden y El siguiente comando, y sabe que uno debe ser utilizado cuando.)

El comando es una cadena y puede ser cualquier cosa que el shell remoto acepte. Tratar

 cmd1 ; cmd2 ; cmd3 

Para ejecutar varios comandos en secuencia. O

 cmd1 && cmd2 && cmd3 

Para ejecutar comandos hasta que uno falla.

Incluso esto podría funcionar:

 cmd1 cmd2 cmd3 

O en Java:

 channel.setCommand("cmd1\ncmd2\ncmd3"); 

Sidenote: No ponga contraseñas y nombres de usuario en el código. Póngalos en un archivo de propiedades y utilice una propiedad del sistema para especificar el nombre del archivo de propiedades. De esta forma, puede mantener el archivo incluso fuera del proyecto y asegurarse de que las contraseñas / nombres de usuario no se filtren.

Configure un objeto SCPInfo para contener el nombre de usuario, la contraseña, el puerto: 22 e ip.

  List<String> commands = new ArrayList<String>(); commands.add("touch test1.txt"); commands.add("touch test2.txt"); commands.add("touch test3.txt"); runCommands(scpInfo, commands); public static void runCommands(SCPInfo scpInfo, List<String> commands){ try { JSch jsch = new JSch(); Session session = jsch.getSession(scpInfo.getUsername(), scpInfo.getIP(), scpInfo.getPort()); session.setPassword(scpInfo.getPassword()); setUpHostKey(session); session.connect(); Channel channel=session.openChannel("shell");//only shell channel.setOutputStream(System.out); PrintStream shellStream = new PrintStream(channel.getOutputStream()); // printStream for convenience channel.connect(); for(String command: commands) { shellStream.println(command); shellStream.flush(); } Thread.sleep(5000); channel.disconnect(); session.disconnect(); } catch (Exception e) { System.err.println("ERROR: Connecting via shell to "+scpInfo.getIP()); e.printStackTrace(); } } private static void setUpHostKey(Session session) { // Note: There are two options to connect // 1: Set StrictHostKeyChecking to no // Create a Properties Object // Set StrictHostKeyChecking to no // session.setConfig(config); // 2: Use the KnownHosts File // Manually ssh into the appropriate machines via unix // Go into the .ssh\known_hosts file and grab the entries for the hosts // Add the entries to a known_hosts file // jsch.setKnownHosts(khfile); java.util.Properties config = new java.util.Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); } 
  • Creación de una aplicación para Android con Jenkins
  • Código de ejemplo de Android SSH
  • ssh en Android para enviar paquetes WOL
  • ¿Cómo puedo comunicarme con un dispositivo Android a través de SSH?
  • Excepción de SSHJ de Android al conectarse () - "Implementación de KeyFactory ECDSA no encontrada"
  • ejecutar el comando SSH en Rasperry Pi con la aplicación para Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.