纯Java通过SSH执行Linux命令的方法及代码
转自:http://ilexes.blog.51cto.com/705330/531352
注:此ssh非彼SSH(Struts+Spring+Hibernate)
在Java中,我们可以通过Runtime去执行一些OS的命令,如:
String[]shell=newString[]{"/bin/sh","-c","ls-l"};
Processp=Runtime.getRuntime().exec(shell);
通过在Linux上执行ssh--help命令,
usage:ssh[-1246AaCfgKkMNnqsTtVvXxY][-bbind_address][-ccipher_spec]
[-D[bind_address:]port][-eescape_char][-Fconfigfile]
[-iidentity_file][-L[bind_address:]port:host:hostport]
[-llogin_name][-mmac_spec][-Octl_cmd][-ooption][-pport]
[-R[bind_address:]port:host:hostport][-Sctl_path]
[-wlocal_tun[:remote_tun]][user@]hostname[command]
不难发现,ssh命令中并不能带密码。
如果不需要登录时,我们可以用这样的方式来执行:
String[] shell = new String[] { " /bin/sh " , " -c " , " ssh [email protected] ls -l " } ; Process p = Runtime.getRuntime().exec(shell);
但是事情往往并不是我们想象的如此简单,绝大部分的客户是不能允许他们的Linux中还存在一个不需要密码就能执行任何命令的帐户的。那么,在Java中就没有任何办法通过ssh登录来执行一些命令吗?
不慌,先来Google一下,从一些网上别人请教的代码的蛛丝蚂迹中,发现了JSch(http://www.jcraft.com/jsch/),这东东还真是不错,来,我们先看看其官方的简介:
JSchisapureJavaimplementationofSSH2.
JSchallowsyoutoconnecttoansshdserveranduseportforwarding,X11forwarding,filetransfer,etc.,andyoucanintegrateitsfunctionalityintoyourownJavaprograms.JSchislicensedunderBSDstylelicense.
这东东支持像telnet一样的ssh的session,SFTP,SCP等。
下面,就让我们来看一个执行ssh命令的通用方法:
public static String sshExecute(String host, String user, String pwd, String command) { String osName = System.getProperty("os.name"); // ps -ef|grep tomcat|grep -v grep|awk '{print $2}' StringBuffer sb = new StringBuffer(); try { JSch jsch = new JSch(); if (osName.toUpperCase().indexOf("WINDOWS") > -1) { jsch.setKnownHosts("c:\\known_hosts"); } else { jsch.setKnownHosts("/root/.ssh/known_hosts"); } Session session = jsch.getSession(user, host, 22); session.setPassword(pwd); session.connect(); Channel channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); InputStream in = channel.getInputStream(); channel.connect(); int nextChar; while (true) { while ((nextChar = in.read()) != -1) { sb.append((char) nextChar); } if (channel.isClosed()) { System.out.println("exit-status: " + channel.getExitStatus()); break; } try { Thread.sleep(1000); } catch (Exception ee) { } } channel.disconnect(); session.disconnect(); } catch (Exception e) { e.printStackTrace(); } return sb.toString(); }
看看,是不是挺简单了。
别忘了,由于这是PureJavaprogram,还有一个优点就是,这样的程序不依赖于OS,可以直接在Windows或者其它OS上运行。
对了,执行这个需要RSA的Key文件,示例如下:
192.168.1.4 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsoINy5sLnrzYCTKBh2UrsqHd62dnnimCZtvq8ojTYt7NcAjjtW2FqmFNO+5x/mTwyY+ssoP5SganxDYs3G016aPZDQdGVZMn/08Is
B7QEIAXEVHtgGIGuLqsdMUBBIxV7KI6BK+OWVwv277tBOgqvPcgeEacviFZb2lZhWr8hv
R2pTrPFBLr+UELejm/Nnf9qWDBjDj/d2o8+ReSwN8dzNJIiFyWdboyUCZfHhxNgiGANFx22
gC4lM+Wk8gkASo/QYDvoUwLFrAJoMdsw0d4pn34bQ0mspaaWy4N0+zrNCPcl8D0Q1R
rAjfYfOiZOSTnxabJ2DLijuq7UgFbn2ESMw==
附:产生此文件的简单方法:可以在Linux中用ssh命令登录一次,这样便在/root/.ssh(假如使用root用户登录到Linux)目录下生成known_hosts文件。