2008-10-14 9 views
66

Was ist die beste Methode für die Durchführung einer scp-Übertragung über die Java-Programmiersprache? Es scheint, als könnte ich dies über JSSE, JSch oder die Hüpfburg-Java-Bibliotheken durchführen. Keine dieser Lösungen scheint eine einfache Antwort zu haben.scp über Java

+2

können Sie nach unten brechen die Probleme, die Sie mit den verschiedenen Bibliotheken haben, warum sie nicht für Sie arbeiten? –

Antwort

50

Ich endete mit Jsch - es war ziemlich einfach, und schien ziemlich gut zu skalieren (Ich war ein paar tausend Dateien alle paar Minuten greifen).

+0

jsch erwies sich als die bessere Alternative, aber die Dokumentation ist schrecklich. Der Tipp von Abarax, sich die Ameisen-Scp-Aufgabe anzusehen, war sehr hilfreich. Es ist wirklich nicht klar, ob das Projekt noch sehr aktiv ist. Danke für den Tipp. –

+23

@LloydMeinholz: Ich schrieb [Javadocs] (http://epaul.github.com/jsch-documentation/simple.javadoc/) für diese Bibliothek. –

+0

Paulo - tolle Arbeit! Sie sehen sehr hilfreich aus. –

2

Die openssh project listet mehrere Java-Alternativen, Trilead SSH for Java scheint zu passen, was Sie verlangen.

+0

Trilead scheint viel reifer zu sein als Jsch, aber es mangelte an sftp und scp Unterstützung, und genau das wollte ich.Derzeit unterstützt sftp nur get und put (ich brauche ls und rm auch) und scp-Unterstützung wurde als experimentell aufgeführt. –

16

Werfen Sie einen Blick here

, dass der Quellcode für Ameisen SCP Aufgabe. Der Code in der "Ausführen" -Methode ist, wo die Schrauben und Muttern davon sind. Dies sollte Ihnen eine ungefähre Vorstellung davon geben, was erforderlich ist. Es benutzt JSch glaube ich.

Alternativ können Sie diese Ant-Task auch direkt aus Ihrem Java-Code ausführen.

2

Ich benutze diese SFTP-API, die SCP namens Zehon hat, es ist großartig, so einfach mit einer Menge Beispielcode zu verwenden. Hier ist die Seite http://www.zehon.com

17

Stecker: Sshj ist die einzige gesunde Wahl! Sehen Sie sich diese Beispiele an, um loszulegen: download, upload.

+4

Nur vernünftige Wahl? –

+1

Ich ging mit sshj über Jsch, da es eine viel einfachere Schnittstelle hatte. – Chris

+0

@shikhar Beispiel-Links sind tot, können Sie aktualisieren? – BillMan

5

Ich wickelte JSch mit einigen Hilfsmethoden es etwas freundlicher zu machen und nannte es

Jscp

Erhältlich hier: https://github.com/willwarren/jscp

SCP-Dienstprogramm einen Ordner TAR, ZIP, und es scp irgendwo, dann entzippe es.

Verbrauch:

// 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") 
      ); 

enthält auch nützliche Klassen - Scp und Exec und ein TarAndGzip, die Arbeit in so ziemlich die gleiche Weise.

1

JSch ist eine nette Bibliothek mit zu arbeiten. Es hat eine recht einfache Antwort auf Ihre Frage.

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); 
    } 
    } 

können Sie bei vollständigen Code finden

http://faisalbhagat.blogspot.com/2013/09/java-uploading-file-remotely-via-scp.html

2

ich bei vielen dieser Lösungen gesucht und viele von ihnen nicht gefallen hat. Vor allem wegen des lästigen Schrittes, Ihre bekannten Hosts zu identifizieren. Das und JSCH ist relativ zum scp-Befehl lächerlich niedrig.

Ich fand eine Bibliothek, die dies nicht erfordert, aber es ist gebündelt und als Befehlszeilenprogramm verwendet.https://code.google.com/p/scp-java-client/

Ich schaute durch den Quellcode und entdeckte, wie man es ohne die Befehlszeile verwendet. Hier ist ein Beispiel für das Hochladen:

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("[email protected]:/path/on/remote"); 
    scp.execute(); 

Der größte Nachteil ist, dass es nicht in einer Maven-Repo ist (das ich finden kann). Aber die Benutzerfreundlichkeit ist es mir wert.

1

jsch hat super für mich gearbeitet. Im Folgenden finden Sie ein Beispiel für eine Methode, die eine Verbindung zum sftp-Server herstellt und Dateien in das angegebene Verzeichnis herunterlädt. Es wird empfohlen, StrictHostKeyChecking nicht zu deaktivieren. Obwohl es etwas schwieriger ist, es einzurichten, sollte aus Sicherheitsgründen die Angabe der bekannten Hosts die Norm sein.

jsch.setKnownHosts ("C: \ Benutzer \ Test \ Bekannte_Hosts"); empfohlen

JSch.setConfig ("StrictHostKeyChecking", "nein"); - nicht

empfohlen
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(); 
      } 
     } 

    } 
1

einige wie hier, landete ich einen Wrapper um die JSch Bibliothek Schreiben auf.

Es heißt way-secshell und es ist auf 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(); 
4

Dies wird High-Level-Lösung, keine Notwendigkeit, neu zu erfinden. Schnell und dreckig!

1) Gehen Sie zuerst zu http://ant.apache.org/bindownload.cgi und laden Sie die neueste Apache Ant-Binärdatei herunter. (heutzutage, apache-ant-1.9.4-bin.zip).

2) die heruntergeladene Datei extrahieren und die JAR ant-jsch.jar ("Apache-ant-1.9.4/lib/ant-jsch.jar") zu finden. Fügen Sie dieses JAR in Ihr Projekt ein. Auch ant-launcher.jar und ant.jar.

3) Gehen Sie zu Jcraft jsch SouceForge Project und laden Sie das Glas herunter. Heutzutage, jsch-0.1.52.jar. Auch Fügen Sie diese JAR in Ihrem Projekt.

Jetzt können Sie easyly Java-Code verwenden, um in die Ant Klassen Scp für Kopieren von Dateien über das Netzwerk oder SSHExec für Befehle in SSH-Servern.

4) Codebeispiel 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(); 
+0

Ich versuche das aber bekam Fehler, wenn irgendeine Lösung dann bitte Kommentar ---> com.jcraft.jsch.JSchException: Session.connect: java.security.NoSuchAlgorithmException: Algorithmus DH nicht verfügbar –

+1

Wenn Sie eine schnelle Lösung benötigen, funktioniert das wie magisch und viel einfacher, als JSch direkt zu benutzen, danke. –

0

Ich brauche Ordner rekursiv zu kopieren, nachdem verschiedene Lösungen versucht, schließlich durch Process am Ende + erwarten/Laich

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 %[email protected]%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(); 
}