Gestione sincrona dell’output
Abbiamo visto che è possibile gestire l’output prodotto da un comando molto semplice come ls
. Il codice visto, però, funzionerà bene soltanto se l’output sarà visualizzato immediatamente, senza ritardi. Subito dopo la chiamata al metodo getStdOut()
, infatti, l’esecuzione del client SSH continuerà, e la sessione potrebbe essere chiusa anche prima che l’intero output venga effettivamente prodotto. Per risolvere questo problema, dobbiamo fare ricorso ad un ulteriore metodo dell’oggetto Session
di Ganymed SSH-2, chiamato waitForCondition
, la cui definizione è la seguente:
public int waitForCondition(int condition_set, long timeout)
Con esso abbiamo la possibilità di specificare quando l’esecuzione potrà continuare, facendo riferimento ad alcune condizioni che possono verificarsi. Il parametro condition_set
, infatti, indicherà il tipo di condizione; quando essa si verificherà, l’esecuzione potrà continuare. Inoltre, per evitare deadlock, possiamo specificare un timeout, oltre il quale l’esecuzione continuerà indipendentemente dal verificarsi della condizione specificata.
Le possibili condizioni sono tutti i membri della classe ChannelCondition di Ganymed SSH-2, ovvero:
Condizione | Descrizione |
---|---|
CLOSED |
Il canale SSH-2 è stato chiuso |
EOF |
È stata raggiunta la fine dell’output da leggere, e non arriveranno altri dati come output del comando inviato |
EXIT_SIGNAL |
Il segnale di uscita dal processo è disponibile |
EXIT_STATUS |
Il processo è stato terminato |
STDERR_DATA |
Sono presenti dati nello std_err che possono essere consumati |
STDOUT_DATA |
Sono presenti dati nello std_out che possono essere consumati |
TIMEOUT |
Si è verificato il timeout specificato |
Per esemplificare quanto detto, supponiamo di volere attendere il completamento dell’esecuzione di un comando, in modo che esso produca interamente un output. Immaginiamo, inoltre, che il comando in questione si chiami my_command
. Il codice che dovremo eseguire sarà il seguente:
Session sess = conn.openSession();
sess.execCommand("my_command");
int condition = ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA | ChannelCondition.EOF;
sess.waitForCondition(condition, 2000);
SCP: copiare file e cartelle
Uno dei comandi a corredo del pacchetto OpenSSH è scp
(che è anche l’acronimo di Secure Copy). Si tratta sostanzialmente di una versione del comando cp
che consente di copiare file remotamente, da un server ad un client SSH e viceversa. Anche Ganymed SSH-2 ci consente di effettuare questa operazione, tramite una classe chiamata SCPClient
. All’interno di essa sono definiti due metodi (con alcuni overload), denominati get
e put
. Il primo consente di copiare un file dal server al client, mentre il secondo effettua il task inverso.
Il codice seguente è un esempio di come utilizzare la classe SCPClient
.
try {
//Creo l'oggetto Connection, ed avvio la connessione
Connection conn = new Connection(ip);
conn.connect();
//Effettuo l'autenticazione...
boolean isAuthenticated = conn.authenticateWithPassword(usr, psw);
//...e verifico che sia andata a buon fine
if (isAuthenticated == false) {
return null;
}
//Creo l'oggetto SCPClient
SCPClient scpc = conn.createSCPClient();
/*
* Non e' necessario gestire alcuna sessione, poiche'
* ogni richiesta inviata tramite SCPClient e'
* mappata su una sessione distinta
*/
String remoteTargetDir = "path/of/remote/directory/";
String localFilePath = "path/of/local/file.test";
String localTargetDir = "path/of/local/directory/";
//Copia il file sul server...
scpc.put(localFilePath, remoteTargetDir);
//...e ottengo lo stesso file dal server
scpc.get(remoteTargetDir + localFilePath, localTargetDir);
//Chiudo la connessione (non ci sono sessioni aperte)
conn.close();
} catch (IOException e) {
return null;
}
L’utilizzo degli altri overload dei metodi get
e put
è molto simile. Per maggiori informazioni, l’apposita pagina della documentazione può essere di aiuto.