java - logo - apache hbase download
scp vía java (13)
¿Cuál es el mejor método para realizar una transferencia scp a través del lenguaje de programación Java? Parece que puedo realizar esto a través de JSSE, JSch o las bibliotecas java castillo hinchable. Ninguna de estas soluciones parece tener una respuesta fácil.
Como algunos aquí, terminé escribiendo un envoltorio alrededor de la biblioteca JSch.
Se llama way-secshell y está alojado en GitHub:
https://github.com/objectos/way-secshell
// scp myfile.txt localhost:/tmp
File file = new File("myfile.txt");
Scp res = WaySSH.scp()
.file(file)
.toHost("localhost")
.at("/tmp")
.send();
Echa un vistazo here
Ese es el código fuente para la tarea SCP de Ants. El código en el método "ejecutar" es donde están las tuercas y los pernos de él. Esto debería darle una buena idea de lo que se requiere. Utiliza JSch, creo.
Alternativamente, también podría ejecutar directamente esta tarea Ant desde su código java.
El proyecto openssh enumera varias alternativas de Java, Trilead SSH para Java parece ajustarse a lo que está pidiendo.
Envolví Jsch con algunos métodos de utilidad para que sea un poco más amigable y lo llamé
Jscp
Disponible aquí: https://github.com/willwarren/jscp
Herramienta SCP para atacar una carpeta, comprimirla y copiarla en algún lugar, luego descomprimirla.
Uso:
// create secure context
SecureContext context = new SecureContext("userName", "localhost");
// set optional security configurations.
context.setTrustAllHosts(true);
context.setPrivateKeyFile(new File("private/key"));
// Console requires JDK 1.7
// System.out.println("enter password:");
// context.setPassword(System.console().readPassword());
Jscp.exec(context,
"src/dir",
"destination/path",
// regex ignore list
Arrays.asList("logs/log[0-9]*.txt",
"backups")
);
También incluye clases útiles: Scp y Exec, y TarAndGzip, que funcionan de la misma manera.
Escribí un servidor scp que es mucho más fácil que otros. Utilizo el proyecto Apache MINA (Apache SSHD) para desarrollarlo. Puede echar un vistazo aquí: https://github.com/boomz/JSCP También puede descargar el archivo /jar
directorio /jar
. ¿Cómo utilizar? Eche un vistazo en: https://github.com/boomz/JSCP/blob/master/src/Main.java
Esta es una solución de alto nivel , no hay necesidad de reinventar. ¡Rápido y sucio!
1) Primero, vaya a http://ant.apache.org/bindownload.cgi y descargue el último binario de Apache Ant. (hoy en día, apache-ant-1.9.4-bin.zip).
2) Extraiga el archivo descargado y encuentre el JAR ant-jsch.jar ("apache-ant-1.9.4 / lib / ant-jsch.jar"). Agregue este JAR en su proyecto . También ant-launcher.jar y ant.jar.
3) Ir a Jcraft jsch SouceForge Project y descargar el jar. Hoy en día, jsch-0.1.52.jar . También agregue este JAR en su proyecto .
Ahora, ¿puede utilizar fácilmente en el código java el Ant Classes Scp para copiar archivos a través de la red o SSHExec para los comandos en los servidores SSH?
4) Ejemplo de código Scp:
// This make scp copy of
// one local file to remote dir
org.apache.tools.ant.taskdefs.optional.ssh.Scp scp = new Scp();
int portSSH = 22;
String srvrSSH = "ssh.your.domain";
String userSSH = "anyuser";
String pswdSSH = new String ( jPasswordField1.getPassword() );
String localFile = "C://localfile.txt";
String remoteDir = "/uploads/";
scp.setPort( portSSH );
scp.setLocalFile( localFile );
scp.setTodir( userSSH + ":" + pswdSSH + "@" + srvrSSH + ":" + remoteDir );
scp.setProject( new Project() );
scp.setTrust( true );
scp.execute();
JSch es una buena biblioteca para trabajar. Tiene una respuesta bastante fácil para tu pregunta.
JSch jsch=new JSch();
Session session=jsch.getSession(user, host, 22);
session.setPassword("password");
Properties config = new Properties();
config.put("StrictHostKeyChecking","no");
session.setConfig(config);
session.connect();
boolean ptimestamp = true;
// exec ''scp -t rfile'' remotely
String command="scp " + (ptimestamp ? "-p" :"") +" -t "+rfile;
Channel channel=session.openChannel("exec");
((ChannelExec)channel).setCommand(command);
// get I/O streams for remote scp
OutputStream out=channel.getOutputStream();
InputStream in=channel.getInputStream();
channel.connect();
if(checkAck(in)!=0){
System.exit(0);
}
File _lfile = new File(lfile);
if(ptimestamp){
command="T "+(_lfile.lastModified()/1000)+" 0";
// The access time should be sent here,
// but it is not accessible with JavaAPI ;-<
command+=(" "+(_lfile.lastModified()/1000)+" 0/n");
out.write(command.getBytes()); out.flush();
if(checkAck(in)!=0){
System.exit(0);
}
}
Puede encontrar el código completo en
http://faisalbhagat.blogspot.com/2013/09/java-uploading-file-remotely-via-scp.html
Miré muchas de estas soluciones y no me gustaron muchas de ellas. Sobre todo porque es un paso molesto tener que identificar a los hosts conocidos. Eso y JSCH están en un nivel ridículamente bajo en relación con el comando scp.
Encontré una biblioteca que no requiere esto, pero se incluye y se utiliza como una herramienta de línea de comandos. https://code.google.com/p/scp-java-client/
Miré a través del código fuente y descubrí cómo usarlo sin la línea de comando. Aquí hay un ejemplo de carga:
uk.co.marcoratto.scp.SCP scp = new uk.co.marcoratto.scp.SCP(new uk.co.marcoratto.scp.listeners.SCPListenerPrintStream());
scp.setUsername("root");
scp.setPassword("blah");
scp.setTrust(true);
scp.setFromUri(file.getAbsolutePath());
scp.setToUri("root@host:/path/on/remote");
scp.execute();
El mayor inconveniente es que no está en un repositorio maven (que pude encontrar). Pero la facilidad de uso me lo merece.
Necesito copiar la carpeta recursivamente, después de probar diferentes soluciones, finalmente termino en ProcessBuilder + expect / spawn
scpFile("192.168.1.1", "root","password","/tmp/1","/tmp");
public void scpFile(String host, String username, String password, String src, String dest) throws Exception {
String[] scpCmd = new String[]{"expect", "-c", String.format("spawn scp -r %s %s@%s:%s/n", src, username, host, dest) +
"expect /"?assword:/"/n" +
String.format("send /"%s//r/"/n", password) +
"expect eof"};
ProcessBuilder pb = new ProcessBuilder(scpCmd);
System.out.println("Run shell command: " + Arrays.toString(scpCmd));
Process process = pb.start();
int errCode = process.waitFor();
System.out.println("Echo command executed, any errors? " + (errCode == 0 ? "No" : "Yes"));
System.out.println("Echo Output:/n" + output(process.getInputStream()));
if(errCode != 0) throw new Exception();
}
Terminé usando Jsch , fue bastante sencillo, y parecía escalar bastante bien (estaba agarrando unos pocos miles de archivos cada pocos minutos).
Utilizo esta API de SFTP que tiene un SCP llamado Zehon, es genial, tan fácil de usar con una gran cantidad de código de muestra. Aquí está el sitio http://www.zehon.com
jsCH me ha funcionado muy bien. A continuación se muestra un ejemplo de un método que se conectará al servidor sftp y descargará archivos al directorio especificado. Se recomienda evitar la desactivación de StrictHostKeyChecking. Aunque es un poco más difícil de configurar, por razones de seguridad, especificar los hosts conocidos debería ser la norma.
jsch.setKnownHosts ("C: / Users / test / known_hosts"); recomendado
JSch.setConfig ("StrictHostKeyChecking", "no"); - no recomendado
import com.jcraft.jsch.*;
public void downloadFtp(String userName, String password, String host, int port, String path) {
Session session = null;
Channel channel = null;
try {
JSch ssh = new JSch();
JSch.setConfig("StrictHostKeyChecking", "no");
session = ssh.getSession(userName, host, port);
session.setPassword(password);
session.connect();
channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftp = (ChannelSftp) channel;
sftp.get(path, "specify path to where you want the files to be output");
} catch (JSchException e) {
System.out.println(userName);
e.printStackTrace();
} catch (SftpException e) {
System.out.println(userName);
e.printStackTrace();
} finally {
if (channel != null) {
channel.disconnect();
}
if (session != null) {
session.disconnect();
}
}
}