Java如何通过ssh远程连接主机并执行命令
作者:朱又炖粉条
Java通过ssh远程连接主机并执行命令
需要用到的jar包:
主体代码:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ch.ethz.ssh2.Connection; import ch.ethz.ssh2.Session; import ch.ethz.ssh2.StreamGobbler; public class SshLinux { private static final Logger log = LoggerFactory.getLogger(SshLinux.class); private static String DEFAULTCHART="UTF-8"; /** * 登录主机 * @return * 登录成功返回true,否则返回false */ public static Connection login(String ip, String userName, String userPwd){ boolean flg=false; Connection conn = null; try { conn = new Connection(ip); conn.connect();//连接 flg=conn.authenticateWithPassword(userName, userPwd);//认证 if(flg){ log.info("=========登录成功========="+conn); return conn; } } catch (IOException e) { log.error("=========登录失败========="+e.getMessage()); e.printStackTrace(); } return conn; } /** * 远程执行shll脚本或者命令 * @param cmd * 即将执行的命令 * @return * 命令执行完后返回的结果值 */ public static String execute(Connection conn,String cmd){ String result=""; try { if(conn !=null){ Session session= conn.openSession();//打开一个会话 session.execCommand(cmd);//执行命令 result=processStdout(session.getStdout(),DEFAULTCHART); //如果为得到标准输出为空,说明脚本执行出错了 if(StringUtils.isBlank(result)){ log.info("得到标准输出为空,链接conn:"+conn+",执行的命令:"+cmd); result=processStdout(session.getStderr(),DEFAULTCHART); }else{ log.info("执行命令成功,链接conn:"+conn+",执行的命令:"+cmd); } conn.close(); session.close(); } } catch (IOException e) { log.info("执行命令失败,链接conn:"+conn+",执行的命令:"+cmd+" "+e.getMessage()); e.printStackTrace(); } return result; } /** * 解析脚本执行返回的结果集 * @param in 输入流对象 * @param charset 编码 * @return * 以纯文本的格式返回 */ private static String processStdout(InputStream in, String charset){ InputStream stdout = new StreamGobbler(in); StringBuffer buffer = new StringBuffer();; try { BufferedReader br = new BufferedReader(new InputStreamReader(stdout,charset)); String line=null; while((line=br.readLine()) != null){ buffer.append(line+"\n"); } } catch (UnsupportedEncodingException e) { log.error("解析脚本出错:"+e.getMessage()); e.printStackTrace(); } catch (IOException e) { log.error("解析脚本出错:"+e.getMessage()); e.printStackTrace(); } return buffer.toString(); } }
注意:ganymed这个jar包,每次只能执行一条命令,如果一条命令执行了没有关闭,再去执行第二条则会throw new IOException("A remote execution has already started.");
若希望同时执行多条命令,可以在传入的cmd字符串中用&&连接多条命令。
如:
那么多条命令执行的所有结果将会一同作为返回的字符串。
ssh 远程脚本执行 java: command not found
ssh 远程主机脚本执行、执行 java -version,报如题错误
[root@doris-fe-01 module]# ./install.sh "java -version "
java -version
doris-fe-01 ...
bash: java: command not found
doris-fe-02 ...
bash: java: command not found### 直接登录远程主机,java -version 正常执行
[root@doris-fe-01 module]# ssh doris-fe-02
Last login: Mon Nov 14 16:54:51 2022
[root@doris-fe-02 ~]# java -version
java version "1.8.0_141"
Java(TM) SE Runtime Environment (build 1.8.0_141-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.141-b15, mixed mode)
处理
export JAVA_HOME=/opt/module/jdk1.8.0_141' >>/etc/bashrc echo 'export PATH=/opt/module/jdk1.8.0_141/bin:$PATH' >>/etc/bashrc ### source /etc/bashrc
[root@doris-fe-01 module]# ./install.sh "java -version "
java -version
doris-fe-01 ...
java version "1.8.0_141"
Java(TM) SE Runtime Environment (build 1.8.0_141-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.141-b15, mixed mode)
...
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。