cmd
A library for Java 8 to run a shell command easily on Unix platforms.
Creating a program that executes a shell command from Java is a tedious task but there are a lot of pitfalls which we almost always fall whenever we write a program to use Runtime#exec()
method.
This library does it well on behalf of you.
To run echo hello
, you can simply do either
public class BasicExample {
public void echoLocally() {
Cmd.cmd("echo hello").stream().forEach(System.out::println);
}
// or
public void echoLocallyWithExplicitShell() {
Cmd.cmd(Shell.local(), "echo hello").stream().forEach(System.out::println);
}
}
Examples above will print out a string hello
to stdout
.
To do it over ssh
, do (make sure you can login yourHost
with yourName
without password before trying this)
public class SshExample {
public void echoRemotely() {
Cmd.cmd(Shell.ssh("yourName", "yourHost"), "echo hello").stream().forEach(System.out::println);
}
}
If you want to specify an identity file (ssh key), you can do
public class SshExample {
public void echoRemotelyWithIdentityFile() {
Cmd.cmd(Shell.ssh("yourName", "yourHost", "/home/yourName/.ssh/id_rsa"), "echo hello").connect().forEach(System.out::println);
}
}
Enjoy.
Installation
cmd requires Java SE8 or later. Following is a maven coordinate for it.
<dependency>
<groupId>com.github.xjj59307</groupId>
<artifactId>cmd</artifactId>
<version>[0.11.0,)</version>
</dependency>
More examples
Redirection
You can pipe commands not only using |
in command line string but also using connect
method. This allows you to make your command line string structured and programmable.
$ sh -c 'echo hello && echo world' | cat -n | sort -r | sed 's/hello/HELLO/' | sed -E 's/^ +//'
A command line above can be written as following with cmd
.
import static com.github.dakusui.cmd.Cmd.cmd;
public class PipeExample {
public void pipe() {
cmd("echo hello && echo world").connect(
cmd("cat -n").connect(
cmd("sort -r").connect(
cmd("sed 's/hello/HELLO/'").connect(
cmd("sed -E 's/^ +//'")
)))
).stream(
).map(
s -> String.format("<%s>", s)
).forEach(
System.out::println
);
}
}
The example above will print something like following.
<2 world>
<1 HELLO>
This can be written in a following way, too.
import static com.github.dakusui.cmd.Cmd.cmd;
public class PipeExample {
public void pipedCommands() {
cmd("echo hello && echo world").connect(
cmd("cat -n | sort -r | sed 's/hello/HELLO/' | sed -E 's/^ +//'")
).stream(
).map(
s -> String.format("<%s>", s)
).forEach(
System.out::println
);
}
}
Tee
You can tee
an output from a command into other commands like a unix command of the name.
import static com.github.dakusui.cmd.Cmd.cat;
import static com.github.dakusui.cmd.Cmd.cmd;
public class TeeExample {
public void tee10K() {
cmd(
"seq 1 10000"
).connect(
cat().pipeline(
stream -> stream.map(
s -> "LEFT:" + s
)
)
).connect(
cat().pipeline(
stream -> stream.map(
s -> "RIGHT:" + s
)
)
).stream(
).forEach(
System.out::println
);
}
}
This will print following output to stdout
.
RIGHT:1
RIGHT:2
LEFT:1
RIGHT:3
LEFT:2
RIGHT:4
RIGHT:5
...