使用Process来远程调用
建立本机到远程服务器之间的免密登录
ssh-keygen
ssh-copy-id user@remote-host
验证免密是否配置成功
ssh user@remote-host
如果未出现输入用户名密码的提示,说明ssh免密配置成功。
接下来尝试执行
ssh user@remote-host "ll /"
此命令可以直接在remote-host上执行ll /
这条命令,列出远程主机根目录下的文件。下面使用Java来调用这段代码。
// 务必使用sh -c cmmand这种执行方式,否则会出现参数无法传递的问题
Process process = Runtime.getRuntime().exec(new String[]{"sh", "-c", "ssh user@remote-host 'll /'"});
// 打印控制台输出
InputStream inputStream = process.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
// 等待脚本执行结束
process.waitFor();
System.out.println(“Finished”);
验证到此,我们把ll /
命令换成sh target-shell.sh
,就可以远程执行目标机器上的脚本了。
Process中waitFor方法的作用
waitFor方法会等待脚本执行完毕。此时执行waitFor的线程会进入阻塞状态。
waitFor方法有两个重载版本:
public abstract int waitFor() throws InterruptedException
public boolean waitFor(long timeout, TimeUnit unit) throws InterruptedException
无参数版本的waitFor方法会无限长时间阻塞线程,直到命令执行结束。方法的返回值为命令的执行结果。对于shell文件来说返回值为exit命令后的数字。通常来说返回值为0代表脚本执行正常结束。
比如说针对以下脚本:
demo.sh
echo "Shell started"
sleep 5
echo "Shell finished"
exit -1
当执行到waitFor的时候,会阻塞当前线程,等待demo.sh
sleep 5秒之后返回。该方法的返回值和脚本的exit值对应,即返回值为-1。
有参数版本的waitFor方法可以设置最大等待时间。如果脚本在到达waitFor方法设置的最大等待时间之前返回,waitFor方法会立即返回true。否则会在超时瞬间返回false。
使用Jsch
Jsch为Java实现的SSH客户端。除此之外Jsch还可以实现SFTP文件传输。
点击此处可以访问Jsch的官方网站。
下面贴出一段示例代码,远程启动目标机器上的elasticsearch服务。
JSch jSch = new JSch();
// 依次提供目标机器用户名,IP地址,端口号
Session session = jSch.getSession("root", "192.168.100.128", 22);
// 设置远程连接用户的密码
session.setPassword("123456");
java.util.Properties config = new java.util.Properties();
// 不检查目标机器公钥的变化
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
// 打开命令执行channel
ChannelExec exec = (ChannelExec)session.openChannel("exec");
// 执行目标机器的elasticsearch启动脚本
exec.setCommand("sh /opt/elasticsearch/master/bin/elasticsearch -d");
exec.connect();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(exec.getInputStream()));
String line;
获取命令输出
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
// 断开channel和session
exec.disconnect();
session.disconnect();
网友评论