2019独角兽企业重金招聘Python工程师标准>>>

我们在日常开发中,有时候会遇到触发一个linux命令,比如清理临时文件,或者触发一个shell命令。那么这个时候就需要通过java去调用shell命令。 这里我们使用java自带的ProcessBuilder 来完成任务。ProcessBuilder类是用于创建操作系统进程。通过本机远程ssh到另外一台机器上去执行shell命令的需求,这种使用方式经常用于一台机器集群管理其他机器的需求。

java里可以通过Ganymed SSH-2, Expect4j等实现ssh登录,基步骤如下:

一、下载安装

从http://www.ganymed.ethz.ch/ssh2/下载,我们用的是ganymed-ssh2-build210.zip

在eclipse里新建一个测试工程,并将解压后的ganymed-ssh2-build210.jar拷到工程的lib目录下,然后在工程属性的java build path里添加这个jar的library。

二、ssh

将解压后的examples目录下的Basic.java 拷到工程的src目录,编译运行以后可以在控制台看到输出结果。除了执行一条命令,也可以执行一个shell脚本。

测试脚本test.sh:

#! /bin/sh
echo "testing shell"
ls

运行cmd的Java程序:

public boolean realRun(String cmd) {cmd = test.sh
//      LocalShellExecutor exe = new LocalShellExecutor();RmtShellExecutor exe = new RmtShellExecutor("192.168.1.118", "22", "root", "123456");
//      RmtShellExecutor exe = new RmtShellExecutor("127.0.0.1", "22", "root", "123456");logger.info("cmd:" + cmd);int ret = exe.exec(cmd);outErr = exe.getErrorMessage();outStr = exe.getResult();result = (ret == 0 ? true : false);if (!result) {logger.error("err:" + outErr);}logger.info("outStr:" + outStr);return result;}

本地调用:

package scnas.controller;import java.io.InputStream;
import java.io.InputStreamReader;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;import scnas.iface.ShellExecutor;
import scnas.model.Const;public class LocalShellExecutor implements ShellExecutor {/**标准输出**/private String outStr;/**错误输出**/private String outErr;@Overridepublic int exec(String cmds) {int ret = -1;try{final Process process = Runtime.getRuntime().exec(cmds);
//          Thread inputThread = new Thread(new Runnable(){
//              @Override
//              public void run()
//              {try {InputStream inputStream = process.getInputStream();InputStreamReader reader = new InputStreamReader(inputStream);int readed = 0;char[] chs = new char[1024];StringBuffer buffer = new StringBuffer();while( (readed=reader.read(chs)) != -1 ){     buffer.append(chs,0,readed);}outStr = buffer.toString();logger.info(outStr);}catch(Exception ex){logger.error(ex.getMessage(), ex);}
//              }
//          });//           Thread errorThread = new Thread(new Runnable(){
//              @Override
//              public void run()
//              {try {InputStream inputStream = process.getErrorStream();InputStreamReader reader = new InputStreamReader(inputStream);int readed = 0;char[] chs = new char[1024];StringBuffer errorBuffer = new StringBuffer();while( (readed=reader.read(chs)) != -1 ){errorBuffer.append(chs,0,readed);}outErr = errorBuffer.toString();}catch(Exception ex){logger.error(ex.getMessage(), ex);}
//              }
//          });//           errorThread.start();
//          inputThread.start();process.getOutputStream().close(); ret = process.waitFor(); } catch(Exception e){ outErr = e.getMessage();} if( ret != 0 )logger.error("LocalShellExecutor ERROR: " + outErr);logger.info("LocalShellExecutor: " + outStr);return ret;}@Overridepublic String getErrorMessage() {return outErr;}@Overridepublic String getResult() {return outStr;}public static void main(String args[]){LocalShellExecutor localShellExecutor = new LocalShellExecutor();localShellExecutor.exec(Const.PATH + Const.HOST);}public String getOutStr() {return outStr;}public void setOutStr(String outStr) {this.outStr = outStr;}public String getOutErr() {return outErr;}public void setOutErr(String outErr) {this.outErr = outErr;}private static final Log logger = LogFactory.getLog(LocalShellExecutor.class);
}

远程调用:

package scnas.controller;import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;import scnas.iface.ShellExecutor;
import scnas.model.Const;
import ch.ethz.ssh2.ChannelCondition;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.SCPClient;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;/*** 远程执行shell脚本类*/
public class RmtShellExecutor implements ShellExecutor{/**  */private Connection conn;/** 远程机器IP */private String     ip;/** 用户名 */private String   port;private String     usr;/** 密码 */private String     psword;private String     charset = Charset.defaultCharset().toString();private static final int TIME_OUT = 1000 * 5 * 60;/**标准输出**/private String outStr;/**错误输出**/private String outErr;private static final Log logger = LogFactory.getLog(RmtShellExecutor.class);/*** 构造函数* @param ip* @param usr* @param ps*/public RmtShellExecutor(String ip, String port, String usr, String ps) {this.ip = ip;this.port = port;this.usr = usr;this.psword = ps;}/*** 登录* * @return* @throws IOException*/private boolean login() throws IOException {conn = new Connection(ip, Integer.parseInt(port));conn.connect();return conn.authenticateWithPassword(usr, psword);}/*** 执行脚本* * @param cmds* @return* @throws Exception*/@Overridepublic int exec(String cmds){InputStream stdOut = null;InputStream stdErr = null;int ret = -1;try {if (login()) {// Open a new {@link Session} on this connectionSession session = conn.openSession();// Execute a command on the remote machine.session.execCommand(cmds);stdOut = new StreamGobbler(session.getStdout());outStr = processStream(stdOut, charset);stdErr = new StreamGobbler(session.getStderr());outErr = processStream(stdErr, charset);session.waitForCondition(ChannelCondition.EXIT_STATUS, TIME_OUT);ret = session.getExitStatus();} else{outErr = "登录远程机器失败:" + ip;}}catch(Exception e){outErr = "远程操作失败:" + ip;}finally{if (conn != null) {conn.close();}IOUtils.closeQuietly(stdOut);IOUtils.closeQuietly(stdErr);}if( ret != 0 ){logger.error("RmtShellExecutor ERROR: " + outErr);
//          Loginfo loginfo = new Loginfo("ERROR", "", "RmtShellExecutor", cmds + " - " + outStr);
//          scnasService.loginfoAdd(loginfo);}else{logger.info(cmds +  ": " + outStr);
//          Loginfo loginfo = new Loginfo("INFO", "", "RmtShellExecutor", cmds + " - " + outErr);
//          scnasService.loginfoAdd(loginfo);}return ret;}public int exec(String cmds, boolean wait){int ret = -1;try {if (login()) {// Open a new {@link Session} on this connectionSession session = conn.openSession();// Execute a command on the remote machine.session.execCommand(cmds);session.waitForCondition(ChannelCondition.EXIT_STATUS, TIME_OUT );ret = session.getExitStatus();} else{outErr = "登录远程机器失败:" + ip;}}catch(Exception e){outErr = "远程操作失败:" + ip;}finally{if (conn != null) {conn.close();}}if( ret != 0 )logger.error("RmtShellExecutor wait ERROR!");return ret;}    public void scp(String localfile, String remoteDirectory){try {if (login()) {SCPClient sCPClient = new SCPClient(conn);sCPClient.put(localfile, remoteDirectory, "0755");} else{outErr = "登录远程机器失败:" + ip;}} catch (IOException e) {outErr = "远程操作失败:" + ip;}finally{if (conn != null) {conn.close();}}}/*** @param in* @param charset* @return* @throws IOException* @throws UnsupportedEncodingException*/private String processStream(InputStream in, String charset) throws Exception {byte[] buf = new byte[1024];StringBuilder sb = new StringBuilder();while (in.read(buf) != -1) {sb.append(new String(buf, charset));buf = new byte[1024];}return sb.toString();}@Overridepublic String getErrorMessage() {return outErr;}@Overridepublic String getResult() {return outStr;}public Connection getConn() {return conn;}public void setConn(Connection conn) {this.conn = conn;}public String getIp() {return ip;}public void setIp(String ip) {this.ip = ip;}public String getPort() {return port;}public void setPort(String port) {this.port = port;}public String getUsr() {return usr;}public void setUsr(String usr) {this.usr = usr;}public String getPsword() {return psword;}public void setPsword(String psword) {this.psword = psword;}public String getCharset() {return charset;}public void setCharset(String charset) {this.charset = charset;}public String getOutStr() {return outStr;}public void setOutStr(String outStr) {this.outStr = outStr;}public String getOutErr() {return outErr;}public void setOutErr(String outErr) {this.outErr = outErr;}public static int getTimeOut() {return TIME_OUT;}public static Log getLogger() {return logger;}public static void main(String args[]){RmtShellExecutor exe = new RmtShellExecutor("10.10.1.101", "22", "root", "123456");System.out.println(Const.SHELL + Const.PATH + Const.HOST);
//        System.out.println("exit state:" + exe.exec("gluster volume status vol4 detail"));
//        System.out.println("result:" + exe.getResult());
//        System.out.println("err:" + exe.getErrorMessage());
//        exe.scp("/tmp/1", "/tmp");exe.exec("scnas peer status");
//        System.out.println("result:" + exe.getResult());}}

在eclipse里运行以后的结果为:

Here is some information about the remote host:
testing shell
1
test.sh
ExitCode: 0

需要注意的是在一个session里只能执行一次命令,因此如果想在server上执行多个命令,要么打开多个session,要么在一个session里去执行一个shell脚本,shell脚本里去执行多个命令。

每次执行完以后,如果正确将返回ExitCode: 0,因此程序里可以通过sess.getExitStatus()来判断命令是否被正确执行。

三、 scp

首先在程序里import ch.ethz.ssh2.SCPClient;

然后通过下面的方法来实现:

SCPClient scpClient = conn.createSCPClient();
scpClient.put("localFiles", "remoteDirectory"); //从本地复制文件到远程目录
scpClient.get("remoteFiles","localDirectory"); //从远程获取文件

如上

public void scp(String localfile, String remoteDirectory){}

例如:

scpClient.put("D:\\localTest.txt", "/home/bill/"); 需要注意的是windows的本地目录要用双斜杠来分隔目录。
scpClient.put("/home/bill/remoteTest.txt", "D:\\");

四、sftp

首先在程序里import ch.ethz.ssh2.SFTPv3Client;

SFTPv3Client sftpClient = new SFTPv3Client(conn);
sftpClient.mkdir("newRemoteDir", 0755); //远程新建目录 ,第二个参数是创建的文件夹的读写权限
sftpClient.rmdir("oldRemoteDir"); //远程删除目录

另外还有创建删除文件,读写文件等接口,参见http://www.ganymed.ethz.ch/ssh2/javadoc/ch/ethz/ssh2/SFTPv3Client.html

转载于:https://my.oschina.net/u/2260184/blog/512114

Ganymed SSH-2相关推荐

  1. ganymed ssh-2 for java,用于java连接问题的Ganymed SSH(Ganymed SSH for java connect issue)

    用于java连接问题的Ganymed SSH(Ganymed SSH for java connect issue) 我们正在使用Ganymed-SSH库并在与另一台机器进行SSH时遇到此错误. [r ...

  2. Java使用Ganymed SSH远程登录服务器并读取文件

    Java使用Ganymed SSH远程登录服务器并读取文件 导入jar包,或配置依赖 <-- ganymed-ssh2-build210.jar --> <dependency> ...

  3. Ganymed ssh小使用

    Ganymed SSH 目录 1 SSH简介 1 2 JAVA实现SSH的项目 1 3 GANYMED SSH 1 3.1 依赖说明 1 3.2 实现简单命令 1 3.2 实现SCP命令 1 SSH简 ...

  4. java 连接远程服务器_java实现连接远程服务器并执行命令的基本原理

    一.所需jar包 需要借助Ganymed SSH的jar包:  ganymed-ssh2-build210.jar 二.实现原理 Ganymed SSH-2 java在整个访问过程中担当SSH的客户端 ...

  5. java 远程连接_java实现连接远程服务器并执行命令的基本原理

    一.所需jar包 需要借助Ganymed SSH的jar包:  ganymed-ssh2-build210.jar 二.实现原理 Ganymed SSH-2 java在整个访问过程中担当SSH的客户端 ...

  6. SSH客户端开发开源组件Ganymed SSH-2 for Java初体验

    1.Ganymed SSH-2 for Java Ganymed SSH-2 for Java是一个纯Java实现的SHH2库. 看官方介绍: Ganymed SSH-2 for Java is a ...

  7. ganymed ssh-2 for java,SSH客户端开发开源组件Ganymed SSH-2 for Java初体验,ganymedssh-2

    SSH客户端开发开源组件Ganymed SSH-2 for Java初体验,ganymedssh-2 1.Ganymed SSH-2 for Java Ganymed SSH-2 for Java是一 ...

  8. ganymed ssh-2 for java_如何利用Ganymed SSH-2模拟SSH操作

    简介:Ganymed SSH-2 for Java is a library which implements the SSH-2 protocol in pure Java (tested on J ...

  9. java ssh 超时时间,Java Ganymed Trlead Orion ssh会话超时

    我正在使用SSH Ganymed库别名Trilead别名Orion. 我试图理解会话的确切行为,因为我需要保持ssh连接打开很长时间(也许永远),并在我的jvm关闭或类似的事情时关闭它. 所以,我的问 ...

  10. Ganymed远程连接SSH

    一.依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http:/ ...

最新文章

  1. 含有多个java程序的文件夹导入MyEclipes 出现错误的解决办法
  2. 正则表达式匹配所有script及其内容_VLOOKUP函数进阶用法:模糊一对多匹配之匹配带关键字的所有内容...
  3. 如何在Java中将字节数组转换为InputStream和OutputStream
  4. console.log()与alert()的区别
  5. Spark精华问答 | Spark的计算方法是什么?
  6. 【八】有验证码登录配置:通过 Cookie 跳过验证码登录接口
  7. 详解C#自动注册Dll(OCX)控件的两种方法(转)
  8. socat 端口转发
  9. 古月 ROS移动机器人实战 二维slam地图构建 笔记
  10. CSDN 空间:“迷你博客”很迷人(2)收藏
  11. android录音声波动画,Android开发:仿微信 录音声波
  12. PHP实现图片合并功能(根据群用户头像生成群logo图片)
  13. 十二星座图(附星座变化)
  14. 06 - 微信公众号的菜单配置
  15. 独家 | 爱奇艺如何用大数据助力娱乐工业革命?
  16. java第三讲:数组(Array)
  17. 【postman简介】
  18. linux下创建nginx虚拟目录详解,通过Samba映射Linux磁盘作为Windows IIS的虚拟目录--梦飞翔的地方(梦翔天空)...
  19. 韩国官员提议加强对加密货币监管的全球合作
  20. python 的fcntl模块

热门文章

  1. 孙志华老师担任第十四届世界易学大会副主席一职
  2. TortoiseSVN更新失败解决(update error)文件更新同步更新到SVN
  3. 《Spark -- The Definitive Guide》学习笔记Note.2
  4. python 学习-range(0)
  5. 【清华大学-郑莉教授】C++语言程序设计 函数的参数函数的内联、重载和系统函数的调用
  6. nodejs第五天 npm yarn pnpm 包管理器
  7. 计算机汽车行业术语,汽车专业名词大全.doc
  8. 基于深度学习的大规模vSLAM场景中的鲁棒视觉位置识别
  9. 5G及无线技术专栏:5G NR信号的解调分析
  10. 5G 模块信号质量判断