Java
Rsync#
Here is an example of configuring and running rsync
from within Java, only
outputting the data from stdout/stderr after the process completes:
import com.github.fracpete.rsync4j.RSync;
import com.github.fracpete.processoutput4j.output.CollectingProcessOutput;
...
RSync rsync = new RSync()
.source("/one/place/")
.destination("/other/place/")
.recursive(true);
// or if you prefer using commandline options:
// rsync.setOptions(new String[]{"-r", "/one/place/", "/other/place/"});
CollectingProcessOutput output = rsync.execute();
System.out.println(output.getStdOut());
System.out.println("Exit code: " + output.getExitCode());
if (output.getExitCode() > 0)
System.err.println(output.getStdErr());
This example outputs stdout/stderr from the rsync
process as it occurs,
rather than waiting till the end:
import com.github.fracpete.rsync4j.RSync;
import com.github.fracpete.processoutput4j.output.ConsoleOutputProcessOutput;
...
RSync rsync = new RSync()
.source("/one/place/")
.destination("/other/place/")
.archive(true)
.delete(true);
ConsoleOutputProcessOutput output = new ConsoleOutputProcessOutput();
output.monitor(rsync.builder());
If you want to process the output (stdout/stderr) from the rsync process
yourself, then you can use StreamingProcessOutput
instead of
ConsoleOutputProcessOutput
. You only need to supply an object of a class
implementing the StreamingProcessOwner
interface. Below is an example
that simply prefixes the output with either [OUT]
or [ERR]
:
import com.github.fracpete.rsync4j.RSync;
import com.github.fracpete.processoutput4j.core.StreamingProcessOutputType;
import com.github.fracpete.processoutput4j.core.StreamingProcessOwner;
import com.github.fracpete.processoutput4j.output.StreamingProcessOutput;
public static class Output implements StreamingProcessOwner {
public StreamingProcessOutputType getOutputType() {
return StreamingProcessOutputType.BOTH;
}
public void processOutput(String line, boolean stdout) {
System.out.println((stdout ? "[OUT] " : "[ERR] ") + line);
}
}
...
RSync rsync = new RSync()
.source("/one/place/")
.destination("/other/place/")
.recursive(true)
.verbose(true);
StreamingProcessOutput output = new StreamingProcessOutput(new Output());
output.monitor(rsync.builder());
Windows#
When supplying the rsh
option with an identity, usually like ssh -i /some/where/key.pub
,
you need to supply the actual Windows binary and Windows path to the identity.
You can use the com.github.fracpete.rsync4j.core.Binaries
class to help you
construct the path properly, for instance:
RSync rsync = new RSync()
.source("C:\\somedir")
.destination("D:\\otherdir")
.recursive(true)
.rsh(Binaries.sshBinary() + " -i " + Binaries.convertPath("C:\\keys\\mykey.pub"));
Multiple sources#
You can specify multiple sources when using the sources
methods.
Either as array:
String[] s = new String[]{
"/first/place/",
"/second/place/",
};
RSync rsync = new RSync()
.sources(s)
.destination("/other/place/")
.recursive(true)
.verbose(true);
Or as java.util.List<String>
:
List<String> s = new ArrayList<>();
s.add("/first/place");
s.add("/second/place");
RSync rsync = new RSync()
.sources(s)
.destination("/other/place/")
.recursive(true)
.verbose(true);
Rsync daemon#
Instead of using rsync via ssh, you can also use the rsync daemon approach.
On the server, you can use something like this as /etc/rsyncd.conf
to make
an upload directory /home/public_rsync
available under the name files
:
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsync.log
port = 12000
charset = utf–8
[files]
path = /home/public_rsync
comment = "public rsync share"
use chroot = true
uid = root
gid = root
read only = false
For simplicity, we just start the daemon (running on port 12000) on the server (192.168.1.100) as root user as follows:
sudo rsync --daemon
The following command will upload the directory /home/myuser/some/where
on the
client to the files
share:
import com.github.fracpete.rsync4j.RSync;
import com.github.fracpete.processoutput4j.output.ConsoleOutputProcessOutput;
...
RSync rsync = new RSync()
.recursive(true)
.times(true)
.dirs(true)
.verbose(true)
.source("/home/myuser/some/where")
.destination("rsync://192.168.1.100:12000/files/");
ConsoleOutputProcessOutput output = new ConsoleOutputProcessOutput();
output.monitor(rsync.builder());
Ssh#
The following command lists all files in the /tmp
directory of the localhost
in verbose mode and also outputting the generated command-line:
import com.github.fracpete.rsync4j.Ssh;
import com.github.fracpete.processoutput4j.output.ConsoleOutputProcessOutput;
...
Ssh ssh = new Ssh()
.outputCommandline(true)
.verbose(1)
.hostname("localhost")
.command("ls /tmp");
ConsoleOutputProcessOutput output = new ConsoleOutputProcessOutput();
output.monitor(ssh.builder());
SshKeyGen#
The following command generates a key file named testkey
in your home
directory of type dsa
, with no pass-phrase, outputting the bubble babble
of the key:
import com.github.fracpete.rsync4j.SshKeyGen;
import com.github.fracpete.processoutput4j.output.ConsoleOutputProcessOutput;
...
SshKeyGen keygen = new SshKeyGen()
.outputCommandline(true)
.verbose(1)
.keyType("dsa")
.newPassPhrase("")
.comment("test key")
.keyFile("~/testkey");
ConsoleOutputProcessOutput output = new ConsoleOutputProcessOutput();
output.monitor(keygen.builder());
SshPass#
If it is not possible to use ssh keys for connecting to a remote machine, you
can fall back on using the user/password approach. For this, you will need
to configure an instance of com.github.fracpete.rsync4j.SshPass
class
and pass it to Rsync
or Ssh
object that requires it.
import com.github.fracpete.rsync4j.Ssh;
import com.github.fracpete.rsync4j.SshPass;
import com.github.fracpete.processoutput4j.output.ConsoleOutputProcessOutput;
...
SshPass sshpass = new SshPass()
.password("mysecretpassword");
Ssh ssh = new Ssh()
.sshPass(sshpass)
.option("StrictHostKeyChecking=no")
.hostname("username@remote.host.com")
.command("ls /tmp");
ConsoleOutputProcessOutput output = new ConsoleOutputProcessOutput();
output.monitor(ssh.builder());