I want to run a command on a remote machine using the RExecClient Apache Commons-Net class.
My code is:
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.net.bsd.RExecClient;
public class TestRlogin {
static final int PORT_NUMBER = 512;
private RExecClient client;
private final String url = "test.corp";
private final String login = "bob";
private final String password = "bob";
public TestRlogin() {
client = new RExecClient();
}
public String run(String cmd) throws IOException {
String res = null;
InputStream is = null;
if (client != null) {
try {
if (!client.isConnected()) {
client.connect(url, PORT_NUMBER);
}
client.rexec(login, password, cmd);
is = client.getInputStream();
if (is != null && is.available() > 0) {
res = IOUtils.toString(is);
} else {
System.err.println("InputStream is not available!");
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
IOUtils.closeQuietly(is);
client.disconnect();
}
} else {
System.err.println("The RLogin client is not connected to "+url);
}
return res;
}
public void main(String[] args) {
TestRlogin trl = new TestRlogin();
try {
System.out.println(trl.run("ls -lrt /tmp;"));
System.out.println(trl.run("tar -xf /tmp/archive.tar;"));
System.out.println(trl.run("ls -lrt /tmp;"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
The ls
command works fine but the tar
command does not extract the archive and returns nothing. The message I get is InputStream is not available!
.
I checked twice the tar archive exists on the server. When I rlogin manually and run the command, nothing is returned but the tar archive is extracted.
I am out of ideas.
I finally solved this problem. It is not necessary to specify the port when connecting.
Also, if you are logged as root, check the $HOME/.rhosts
file. When logged as non root, configure both $HOME/.rhosts
and /etc/hosts.equiv
.
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.net.bsd.RExecClient;
public class TestRlogin {
private RExecClient client;
private final String url = "test.corp";
private final String login = "bob";
private final String password = "bob";
public TestRlogin() {
client = new RExecClient();
}
public String run(String cmd) throws IOException {
String res = null;
InputStream is = null;
if (client != null) {
try {
if (!client.isConnected()) {
client.connect(url);
}
client.rexec(login, password, cmd);
is = client.getInputStream();
if (is != null && is.available() > 0) {
res = IOUtils.toString(is);
} else {
System.err.println("InputStream is not available!");
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
IOUtils.closeQuietly(is);
client.disconnect();
}
} else {
System.err.println("The RLogin client is not connected to "+url);
}
return res;
}
public void main(String[] args) {
TestRlogin trl = new TestRlogin();
try {
System.out.println(trl.run("ls -lrt /tmp;"));
System.out.println(trl.run("tar -xf /tmp/archive.tar;"));
System.out.println(trl.run("ls -lrt /tmp;"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
But I still have a question. How to check the command terminated correctly (I posted the question here)? Maybe it is possible to use the method addProtocolCommandListener
from the SocketClient class. I saw there is a protected method fireReplyReceived
.
Thanks for the help.