Avatar billede hite Nybegynder
01. juli 2005 - 11:20 Der er 14 kommentarer og
1 løsning

Flere kommandoer til Process

Hej eksperter.

Jeg sidder og vil gerne udføre en sekvens af kommandoer fra mit javaprogram. (Jeg bruger linux, men det er ikke drabelig vigtigt). Det mit program bør gøre er først at kalde
    ssh server
hernæst skal programmet være i stand til at indtaste passwordet
    ******
og afhængig af om dette lykkes udføre en kommando på serveren.

Jeg er ikke interesseret i at oprette et server/client interface i java, men kun i at afvikle ssh kommandoen og tilhørende password.

Jeg har rodet en masse med Runtime.getRuntime().exec(...), men jeg kan ikke få den til at modtage mere end en enkelt kommando ad gangen (f.eks. echo "hello world").

Kan nogen hjælpe?
Avatar billede arne_v Ekspert
01. juli 2005 - 12:01 #1
Runtime.getRuntime().exec(...) udfører kun en kommando men du kan jo hente
input og output stream fra processen og læse/skrive.
Avatar billede hite Nybegynder
01. juli 2005 - 12:03 #2
Det tænkte jeg også, men jeg kan ikke få det implementeret. Kunne du give et eksempel?
Avatar billede hite Nybegynder
01. juli 2005 - 12:09 #3
Sig hvis du vil have flere point!
Avatar billede hite Nybegynder
01. juli 2005 - 13:55 #4
Jeg er villig til at ødsle
Avatar billede arne_v Ekspert
01. juli 2005 - 14:17 #5
det er ikke points

men jeg får først tid til at prøve i aften
Avatar billede arne_v Ekspert
01. juli 2005 - 19:35 #6
her er et lille eksempel:


import java.io.*;

public class Exec {
    public static void main(String[] args) throws IOException {
        PrintWriter java = new PrintWriter(new FileWriter("Dupper.java"));
        java.println("import java.io.*;");
        java.println("");
        java.println("public class Dupper {");
        java.println("    public static void main(String[] args) throws IOException {");
        java.println("        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));");
        java.println("        String line;");
        java.println("        line = br.readLine();");
        java.println("        System.out.println(line + line);");
        java.println("        line = br.readLine();");
        java.println("        System.out.println(line + line);");
        java.println("        line = br.readLine();");
        java.println("        System.out.println(line + line);");
        java.println("    }");
        java.println("}");
        java.close();
        Runtime.getRuntime().exec("javac Dupper.java");
        Process p = Runtime.getRuntime().exec("java -classpath . Dupper");
        PrintWriter pw = new PrintWriter(p.getOutputStream());
        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
        pw.println("a");
        pw.flush();
        line = br.readLine();
        System.out.println(line);
        pw.println("bb");
        pw.flush();
        line = br.readLine();
        System.out.println(line);
        pw.println("ccc");
        pw.flush();
        line = br.readLine();
        System.out.println(line);
    }
}
Avatar billede arne_v Ekspert
01. juli 2005 - 19:35 #7
som altså virker

jeg garanterer ikke for at det virker med ssh !
Avatar billede hite Nybegynder
01. juli 2005 - 22:03 #8
Ok .. i spørgsmålet bad jeg jo om ssh, så jeg håber du vil kommentere på mit eget forsøg. Jeg prøver nu med en modificeret udgave af din kode at forbinde til min ssh server, og køre ll .. here goes:

import java.io.*;

public class Exec {
    public static void main(String[] args) throws IOException {
        Process p = Runtime.getRuntime().exec("ssh hite@min_server.dk");
        PrintWriter pw = new PrintWriter(p.getOutputStream());
        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
    System.out.println("venter på password prompt");

    try{
        Thread.sleep(1000);
    }catch(Exception e){}
        pw.println("mit_eget_password");
        pw.flush();
    System.out.println("venter på klar prompt");

    try{
        Thread.sleep(1000);
    }catch(Exception e){}
        pw.println("ll");
        pw.flush();
    System.out.println("efter ll");
        line = br.readLine();
        System.out.println(line);
        pw.println("logout");
        pw.flush();
    System.out.println("afslut");
    }
}
Avatar billede hite Nybegynder
01. juli 2005 - 22:04 #9
Output er som følger:
C:\Dokumenter\KredsDesign>java Exec
venter pÕ password prompt
venter pÕ klar prompt
efter ll
<her trykker jeg Ctrl+C>
C:\Dokumenter\KredsDesign>
Avatar billede hite Nybegynder
01. juli 2005 - 22:05 #10
Problemet er så at den hænger når jeg forsøger at skrive fra br
Avatar billede arne_v Ekspert
01. juli 2005 - 22:08 #11
hm

du har anvendt koden som jeg også ville

jeg er lidt bange for at der måske er specielle ting ved ssh (den er jo næppe
linie orienteret men derimod taste tryk orienteret)
Avatar billede hite Nybegynder
01. juli 2005 - 22:36 #12
Åh gud. Nå. Du har som rigeligt fortjent point, så svarsvar. Tusind tak for hjælpen.. det var rart at du gad.

God aften
Avatar billede arne_v Ekspert
01. juli 2005 - 22:55 #13
jeg tror at du skal droppe Runtime exec og kigge på SSLSocket

du skal skrive meget mere kode, men jeg tror at det kan bringes til at virke

og svar
Avatar billede hite Nybegynder
16. juli 2005 - 11:12 #14
Jeg fik løst problemet .. det endte jo med at være mere ssh-orienteret end Process orienteret, men jeg vedlægger en (noget lang) kode som gør det jeg ønskede. I øvrigt kan ideen med at læse og skrive til stdin og stdout også bruges til Process eksemplet. Arne_v, jeg fik rigeligt brugt det du skrev til mig. Den vedlagte kode er en modificeret udgave af eksemplerne der følger med mindterm ssh systemet. Mindterm jar-filen skal bruges for at køre dette eksempel.

/******************************************************************************
*
* Copyright (c) 1999-2003 AppGate Network Security AB. All Rights Reserved.
*
* This file contains Original Code and/or Modifications of Original Code as
* defined in and that are subject to the MindTerm Public Source License,
* Version 2.0, (the 'License'). You may not use this file except in compliance
* with the License.
*
* You should have received a copy of the MindTerm Public Source License
* along with this software; see the file LICENSE.  If not, write to
* AppGate Network Security AB, Otterhallegatan 2, SE-41118 Goteborg, SWEDEN
*
*****************************************************************************/


import java.net.Socket;

import java.io.*;

import com.mindbright.jca.security.SecureRandom;
import com.mindbright.util.SecureRandomAndPad;
import com.mindbright.util.RandomSeed;

import com.mindbright.ssh2.SSH2Transport;
import com.mindbright.ssh2.SSH2Preferences;
import com.mindbright.ssh2.SSH2SimpleClient;
import com.mindbright.ssh2.SSH2ConsoleRemote;

/**
* This is a variant of RunRemoteCommand2 which processes the stdio streams
* slightly differently, otherwise it does exactly the same thing.
*/
public class RunRemoteCommand2 {
  private static char EOT = (char)4;//ascii: 4 = End Of Transmission
 
  private static SSH2SimpleClient client;
  private static SSH2ConsoleRemote console;
 
  private static OutputStream cmdRunner;
  private static InputStream stdout;
 
  public static void main(String[] argv) {
    try {

        //Start up ssh connection
        initConnection(    "192.168.1.100", "hite", "ngeShaekan", 22);

        //Now execute some commands
        System.out.print(issueCommand("cat"));
        System.out.println("\n ================ THATS ONE ===============");
        System.out.print(issueCommand("mi"));
        System.out.println("\n ================ THATS TWO ===============");
        System.out.print(issueCommand(""+EOT));
        System.out.println("\n =============== THATS THREE ==============");
        System.out.print(issueCommand("logout"));
        System.out.println("\n ================ THATS FOUR ==============");
       
        //CLose down connection
        endConnection();
    } catch (Exception e) {
        System.out.println("An error occured: " + e);
        System.exit(1);
    }
  }

  //Method for issuing commands, and recieving data
  private static String issueCommand(String cmd) throws Exception{
      System.out.println("ISSUING COMMAND: "+cmd+"\n\r");

      //Issue the command
      String fullCmd = cmd.concat("\n");
    cmdRunner.write(fullCmd.getBytes());
   
    //Wait for the output to return from server .. this could get ugly
    Thread.sleep(1000);
   
    //Read the output
    String ret = "";
    char c;
    while(((c = (char)stdout.read()) != -1) && stdout.available()>0){
          ret += c;
    }
     
      return ret;
  }
 
  private static void initConnection(String server, String user, String passwd, int port)
      throws Exception{

      SSH2Preferences prefs = new SSH2Preferences();

    /*
    * Connect to the server and authenticate using plain password
    * authentication (if other authentication method needed check other
    * constructors for SSH2SimpleClient).  */
    Socket serverSocket    = new Socket(server, port);
    SSH2Transport transport = new SSH2Transport(serverSocket, prefs,
                        createSecureRandom());
    client = new SSH2SimpleClient(transport,
                          user, passwd);

    /*
    * Create the remote console to use for command execution. Here we
    * redirect stderr of all sessions started with this console to our
    * own stderr (NOTE: stdout is NOT redirected here but is instead
    * fetched below).
    */
    console = new SSH2ConsoleRemote(client.getConnection(), null, System.err);

   
    /*
    * Start a shell on server (note: we don't want a PTY here)
    */
    if(!console.shell(true, "dumb", 20, 80)) {
        throw new Exception("Couldn't execute shell on server!");
    }
   
    /*
    * Fetch the internal stdout stream and wrap it in a BufferedReader
    * for convenience.
    */
    stdout = console.getStdOut();
   
   
    cmdRunner = console.getStdIn();

    Thread.sleep(2000);
     
  }
 
  private static void endConnection() throws Exception{
      /*
    * Retrieve the exit status of the command (from the remote end).
    */
    int exitStatus = console.waitForExitStatus();

    /*
    * Disconnect the transport layer gracefully
    */
    client.getTransport().normalDisconnect("User disconnects");

    /*
    * Exit with same status as remote command did
    */
    System.exit(exitStatus);
  }
 
  public static SecureRandomAndPad createSecureRandom() {
    /* NOTE, this is how it should be done if you want good
    * randomness, however good randomness takes time so we settle with
    * just some low-entropy garbage here.
    *
    * RandomSeed seed = new RandomSeed("/dev/random", "/dev/urandom");
    * byte[] s = seed.getBytesBlocking(20);
    * return new SecureRandomAndPad(new SecureRandom(s));
    *
    */
    byte[] seed = RandomSeed.getSystemStateHash();
    return new SecureRandomAndPad(new SecureRandom(seed));
  }

}
Avatar billede hite Nybegynder
16. juli 2005 - 11:17 #15
Hehe .. og bare rolig .. password er tilfældigt valgt.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester