# ssh connection; Zugriff auf 'screen' Prozess



## Lodorvonhal (9. Feb 2014)

Hallo,

ich bin dabei eine Anwendung zu schreiben, welche auf meinen Linux-Server (Ubuntu) per ssh Verbindung zugreift. Ich realisiere das per JSch. Zusätzlich möchte ich in der Verbindung auf einen screen-Prozess zugreifen.

Dieser Code funktioniert auch ohne Probleme (Example von jcraft.com):


```
JSch jsch = new JSch();

Session session = jsch.getSession(user, host, 22);
session.setPassword(password);

session.setConfig("StrictHostKeyChecking", "no");

session.connect(10*1000);

Channel channel=session.openChannel("shell");
Channel screen = null;
InputStream is = new ByteArrayInputStream(command.getBytes());
channel.setInputStream(is);
		    
channel.setOutputStream(System.out);
channel.connect(15 * 1000);

Thread.sleep(3*1000);
		    
channel.disconnect();
session.disconnect();
```

Erster Gedanke war, dass ich per command über ein Befehl an den screen Prozess senden könnte. 


```
String command = "screen -S SITZUNG -X stuff $'BEFEHL\n'\n";
```

Soweit geht das auch. Mein Problem ist, dass ich bei bestimmten Befehlen auch Rückgaben in der Konsole bekommen. Diese möchte ich auch verarbeiten.

Hat jemand einen Ansatz wie ich an den screen Prozess per Java drankomme um direkt damit zu arbeiten?


Danke fürs lesen.
MFG


----------



## Barista (10. Feb 2014)

Wenn Du Runtime.exec benutzt, bekommst Du ein Process-Objekt zurück,
welches auch die Methoden


```
abstract public OutputStream getOutputStream();

abstract public InputStream getInputStream();

abstract public InputStream getErrorStream();
```

zur Verfügung stellt.

Ich habe vor vielen Jahren da mal was unter Windows gemacht.

Da war wichtig, die Streams in eigenen Threads auszulesen,
damit das aufgerufene Programm nicht blockiert.


----------



## Sen-Mithrarin (10. Feb 2014)

@barista
die antwort hat mal nichts mit der frage zu tun ... du hast nicht mal verstanden worum es geht

@TO
spontan würde ich behaupten das du einfach über das commando "screen -r" dich an den screen hängen kannst ... nur wie du dann das "CTRL + A + D" zum detachen senden kannst ... kein plan


----------



## turtle (10. Feb 2014)

Dieser Post liest sich viel versprechend, habe es aber nicht selber probiert.


----------



## Lodorvonhal (11. Feb 2014)

Hallo und Danke für Eure Antworten. Sry das ich jetzt erst antworte, bei mir war gestern das Internet weg. :shock:

@Barista
Ich habe mit dem Runtime.exec noch nicht gearbeitet. Aber so wie ich das Verstanden habe kann ich damit nur auf plattformeigene Prozesse zugreifen. Ich möchte aber eine App erstellen, welche einen Zugriff auf den Linux Prozess hat.

Trotz alle dem habe ich gesehn das JSch auch so etwas hat. simple JSch API

@Sen-Mithrarin
Danke für den Hinweis, das Ganze hat mich auf eine Idee gebracht um der Lösung ein Stück näher zu kommen.

@turtle
Bezogen auf den Link oben habe ich mit das Beispiel noch einmal angeschaut. Danke.


Zusammenfassen bin ich ein Stück weiter gekommen. Hier ein paar Codeauszüge:


```
String command2 = "screen -rx SITZUNG\n";

Channel channel = session.openChannel("exec");
((ChannelExec)channel).setCommand(command2);
((ChannelExec)channel).setPty(true);
```

Ich hab den Cannel-Typ auf 'exec' geändert. Dadurch bekomme ich Zugriff auf den Prozess. Den Befehl habe ich dahingehend geändert, das ich Zugriff auf den screen bekomme. den Parameter '-r' zum Aufnehmen der Sitzung und explizit '-rx' um einen Zugriff von mehreren Clients gleichzeitig zu erlauben.

Zunächst bekam ich dann den Fehler "Must be connected to a terminal". Daher habe ich die Methode 'setPty' verwendet, welche ein Pseudo Terminal erstellt.

Wenn ich mir nun den Outstream ausgebe, bekomme ich die Ausgabe des screen-Prozess. :applaus:
Danke für die Hilfe dazu. 


Leider komme ich nun noch nicht weiter. Ich kann nun keine spezifischen Befehle an den screen schicken. Bekomme immer Fehlermeldungen, dass die Befehle nicht existieren. Daher vermute ich, dass ich noch kein direktes Objekt des screen habe, sondern nur ein Zugriff auf den Stream.

Ich habe die Anwendung nun so erweitert, dass ich wie im Beispiel aus dem ersten Post einen Befehl per stuff an den screen sende. Mit der Erweiterung von heute kann ich das Ergebnis sehen. Nur ist das Ganze ein wenig Holzhammer.

Ich versuche mal weiter. Wenn jemand noch Ansätze oder Ideen hat immer her damit.


----------



## Lodorvonhal (11. Feb 2014)

Sry für den Doppelpost. Aber ich habe die Antowort.

Ich sag noch das ich nur Zugriff auf den Stream habe. Und das war auch die Lösung. :bloed:

Ich sende einfach über den Inputstream den Befehl an den screen.


```
InputStream is = new ByteArrayInputStream(command2.getBytes());
 channel.setInputStream(is);
```

Und es geht. Ich Danke allen nochmal für die Hilfe und Ansätze. Hier folgend der funktionierende Code.


```
public static void main(String[] args) {
		
	    String user = "user";
	    String password = "password";
	    String host = "host";

	    String command = "screen -rx SITZUNG\n"; // Zugriff auf den Screen
	    String command2 = "BEEHL_AN_SCREEN\n"; // Befehl an den Screen

	    try
	        {
	    	JSch jsch = new JSch();
		    
		    Session session = jsch.getSession(user, host, 22);
		    session.setPassword(password);

		    session.setConfig("StrictHostKeyChecking", "no");
		    session.connect(10*1000);

		    Channel channel = session.openChannel("exec");
		    ((ChannelExec)channel).setCommand(command);
		    ((ChannelExec)channel).setPty(true);
		    
		    InputStream is = new ByteArrayInputStream(command2.getBytes());
		    channel.setInputStream(is);
		    
		    channel.setOutputStream(System.out);
		    
		    channel.connect(15 * 1000);
		    Thread.sleep(3*1000);
		    channel.disconnect();

		    session.disconnect();
	        }
	    catch(Exception e){System.err.print(e);}
	    }
```


----------

