纯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 AAAAB3NzaC1yc2EAAAABIwAAAQEAsoINy5sLnrzYCTKBh2UrsqHd62dnnim

CZtvq8ojTYt7NcAjjtW2FqmFNO+5x/mTwyY+ssoP5SganxDYs3G016aPZDQdGVZMn/08Is

B7QEIAXEVHtgGIGuLqsdMUBBIxV7KI6BK+OWVwv277tBOgqvPcgeEacviFZb2lZhWr8hv

R2pTrPFBLr+UELejm/Nnf9qWDBjDj/d2o8+ReSwN8dzNJIiFyWdboyUCZfHhxNgiGANFx22

gC4lM+Wk8gkASo/QYDvoUwLFrAJoMdsw0d4pn34bQ0mspaaWy4N0+zrNCPcl8D0Q1R

rAjfYfOiZOSTnxabJ2DLijuq7UgFbn2ESMw== 

附:产生此文件的简单方法:可以在Linux中用ssh命令登录一次,这样便在/root/.ssh(假如使用root用户登录到Linux)目录下生成known_hosts文件。

相关推荐