Ganymed "tail -f"?

Hallo,

Ich habe folgendes Problem:

Ich versuche ein Java-Programm zu schreiben, welches remote bestimmte Shell-Kommandos ausführt.
Bisher funktioniert das auch ganz gut, ich bekomme allerdings Probleme bei Kommandos, die nicht sofort abgeschlossen sind, sonder weiterlaufen, wie z.B. “tail -f”

Hier mal die entscheidenden Codeschnipsel:

    public void exectueCommand(String command, int machine) {
        char c = 10;
        try {
            Session session = connection.openSession();
            session.execCommand(command);
            InputStream stdout = new StreamGobbler(session.getStdout());
            BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
            String line = br.readLine();
            while(line != null) {
                textAreaP1.setText(textAreaP1.getText() + c + line);
                line = br.readLine();
            }

        } catch (IOException ex) {
            Logger.getLogger(MoveStackView.class.getName()).log(Level.SEVERE, null, ex);
            textAreaP1.setText(textAreaP1.getText() + c + "An Error occured");
        }
    }

Ausgabe bei einem “ls -l” funktioniert und sieht wie folgt aus:

insgesamt 1560
-rw-r--r-- 1 user users       0 17. Dez 10:06 error.log
-rw-r--r-- 1 user users 1593951 17. Dez 13:56 reader.jar

Bei “tail -f” hängt er sich aber (verständlicherweise) auf und an dem Punkt komme ich nicht weiter, wie schaffe ich es, dass er den Befehl im Hintergrund laufen lässt und mir aber die Ausgabe ins Textfeld schreibt?
Und meine anschließende Frage wäre, wie ich das “tail -f” dann abbrechen kann.

Danke im Vorraus
Gossi

exectueCommand wird von einem Button, vom AWT-Thread ausgeführt?
das darf eben nicht sein, muss in einen eigenen Thread oder SwingWorker usw.,
bekanntes Thema, auch dir bekannt oder zu finden?

wenn du daran arbeitest, dann teste es vielleicht lieber mit einer Dummy-Ausgabe:
Schleife Ausgabe 1-5, dazwischen je 1 sec Pause


wie man das Kommando weiterarbeiten lassen könnte (bzw. falls das automatisch kommt dann wie angesprochen zu beenden)?..
Suche ‘Ganymed java interactive’ führte zu

http://www.ganymed.ethz.ch/ssh2/javadoc/ch/ethz/ssh2/InteractiveCallback.html
“An InteractiveCallback is used to respond to challenges sent by the server if authentication mode “keyboard-interactive” is selected.”

aber grundsätzlich wohl eine Frage für Bedienungsanleitung, welche es hoffentlich gibt und da sollten solche Fälle abgebildet sein, sonst recht unbrauchbar

[QUOTE=SlaterB]exectueCommand wird von einem Button, vom AWT-Thread ausgeführt?
das darf eben nicht sein, muss in einen eigenen Thread oder SwingWorker usw.,
bekanntes Thema, auch dir bekannt oder zu finden?

Themen bekannt, sind aber weniger das Problem, kommt später, da dann mehrere dieser Kommandos gleichzeitig ausgeführt werden müssen

wenn du daran arbeitest, dann teste es vielleicht lieber mit einer Dummy-Ausgabe:
Schleife Ausgabe 1-5, dazwischen je 1 sec Pause

Funktioniert, einziges Problem, die Ausgabe kommt dann erst nach 5 Sekunden, da er wartet bis das Script fertig ist


wie man das Kommando weiterarbeiten lassen könnte (bzw. falls das automatisch kommt dann wie angesprochen zu beenden)?..
Suche ‚Ganymed java interactive‘ führte zu

http://www.ganymed.ethz.ch/ssh2/javadoc/ch/ethz/ssh2/InteractiveCallback.html
„An InteractiveCallback is used to respond to challenges sent by the server if authentication mode „keyboard-interactive“ is selected.“

Funktioniert bei dem Erstellen der Connection zur Authentifikation, leider nicht bei Session (wo ich nen Kommando benutze)

aber grundsätzlich wohl eine Frage für Bedienungsanleitung, welche es hoffentlich gibt und da sollten solche Fälle abgebildet sein, sonst recht unbrauchbar[/QUOTE]

Bedienungsanleitung gibbet leider nicht und in den Beispielen hab ich bisher auch noch nichts gefunden was diesen Fall abdeckt :frowning:

Aber danke trotzdem :slight_smile:

einen Versuch habe ich noch frei:


inklusive dem verlinkten

[QUOTE=SlaterB]einen Versuch habe ich noch frei:


inklusive dem verlinkten
https://gist.github.com/anonymous/4267827[/QUOTE]

Sorry das ich erst so spät antworte.

Also, an sich sieht das nicht schlecht aus, aber ich muss erstmal schauen, wie ich mich mit JSch per Public Key einlogge, Infos folgen asap

Update:
Ich habe jetzt die Key Auth. hinzugefügt

            jsch.addIdentity("C:[...]\\id_rsa");

            com.jcraft.jsch.Session session=jsch.getSession(username, hostnameTest);
            session.setPassword(password);

            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);```
Die Properties müssen gesetzt werden, da (ich) ansonsten eine UnknownHostKey exception bekommen hätte.

Das Problem besteht aber weiterhin, zumindest ein "tail -f" funktioniert mit dem von dir verlinkten Gist-Hub Code leider nicht, er hängt sich weiterhin auf :(

*** Edit ***

So, es funzt :D

Ich habe eine neue Klasse erstellt:

```import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author gossmann
 */
public class Executer implements Runnable {

    private Connection connection;
    private String command;

    private InputStream stdout;

    public Executer(Connection con, String command) {
        this.connection = con;
        this.command = command;

        Thread th = new Thread(this);
        th.start();
    }

    public void exectueCommand(String command) {
        char c = 10;
        try {
            Session session = connection.openSession();
            session.execCommand(command);

            stdout = new StreamGobbler(session.getStdout());
        } catch (IOException ex) {
            Logger.getLogger(Executer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public InputStream getStream() {
        return this.stdout;
    }

    public void run() {
        this.exectueCommand(command);
    }

}```

Diese Klasse wird beim betätigen des Buttons in der Hauptklasse angesprochen:
```exec = new Executer(connection, textCommand.getText());```

Anschließend wird hier ein Thread gestartet, der den InputStream der Executer-Klasse ausliest:
    th = new Thread(this);
    th.start();

public void run() {
    try {
        Thread.sleep(500);
        InputStream stdout = exec.getStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
        String line = br.readLine();
        char c = 10;
        while(line != null) {
            textArea.setText(textArea.getText() + c + line);
            line = br.readLine();
        }
    } catch (Exception ex) {
        Logger.getLogger(MoveStackView.class.getName()).log(Level.SEVERE, null, ex);
    }
}```

Einziges Problem (hat aber nichts mehr mit dem Thema zu tun:

            th.interrupt();
        }```
geht leider nicht :(