首先我们需要先引入依赖
Jar包:ganymed-ssh2-build210.jar
<dependency>
<groupId>ch.ethz.ganymed</groupId>
<artifactId>ganymed-ssh2</artifactId>
<version>build210</version>
</dependency>
因为我们可能需要用到这里的一些类
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
话不多说,上代码
public static void main(String[] args) throws Exception {
//需要执行的命令
String command = "cat log.txt";
//host
String host="dcmaster02";
Connection conn= new Connection(host);
Session ssh = null;
conn.connect();
String username="hadoop";
String password="hadoop";
boolean isconn=conn.authenticateWithPassword(username, password);
if(!isconn){
System.out.println("用户名称或者是密码不正确");
}else{
System.out.println("已经连接OK");
ssh=conn.openSession();
//执行
ssh.execCommand(command);
//返回正确输出
InputStream stdout = new StreamGobbler(ssh.getStdout());
//返回错误输出
InputStream stderr = new StreamGobbler(ssh.getStderr());
BufferedReader stdoutReader = new BufferedReader(
new InputStreamReader(stdout));
BufferedReader stderrReader = new BufferedReader(
new InputStreamReader(stderr));
System.out.println("Here is the output from stdout:");
while (true) {
String line = stdoutReader.readLine();
if (line == null)
break;
System.out.println(line);
}
System.out.println("Here is the output from stderr:");
while (true) {
String line = stderrReader.readLine();
if (line == null)
break;
System.out.println(line);
}
}
ssh.close();
conn.close();
}
这样就可以执行成功了,但若是执行简单的Shell命令:(如 jps 、last 这样的命令 ),一般不会出问题
ssh.execCommand(command);
重点:遇到问题:
用方法execCommand执行Shell命令的时候,会遇到获取不全环境变量的问题,比如执行 hadoop fs -ls 可能会报找不到hadoop 命令的异常,试着用execCommand执行打印环境变量信息的时候,输出的环境变量不完整与Linux主机建立连接的时候会默认读取环境变量等信息,可能是因为session刚刚建立还没有读取完默认信息的时候,execCommand就执行了Shell命令
例如我执行
String command="yarn application -kill application_1597932203385_0571";
ssh.execCommand(command);
打印结果
已经连接OK
Here is the output from stdout:
Here is the output from stderr:
bash: yarn: command not found
bash: yarn: command not found,就是因为session刚刚建立还没有读取完默认信息的时候,execCommand就执行了Shell命令
解决办法:
换另外一种方式来执行Shell命令:
// 建立虚拟终端
ssh.requestPTY("bash");
// 打开一个Shell
ssh.startShell();
// 准备输入命令
PrintWriter out = new PrintWriter(ssh.getStdin());
// 输入待执行命令
out.println(command);
out.println("exit");
// 关闭输入流
out.close();
// 等待,除非1.连接关闭;2.输出数据传送完毕;3.进程状态为退出;4.超时
ssh.waitForCondition(ChannelCondition.CLOSED | ChannelCondition.EOF | ChannelCondition.EXIT_STATUS , 10000);
用这种方式执行Shell命令,会避免环境变量读取不全的问题,第7步里有许多标识可以用,比如当exit命令执行后或者超过了timeout时间,则session关闭 ,这里需要注意,当一个Shell命令执行时间过长时,会遇到ssh连接超时的问题,可以将Linux主机的sshd_config的参数ClientAliveInterval设为60,同时将第最后一步中timeout时间设置很大,来保证命令执行完毕