随笔-193  评论-715  文章-1  trackbacks-0

本Blog所有内容不得随意转载,版权属于作者所有。如需转载请与作者联系( fastzch@163.com )。
未经许可的转载,本人保留一切法律权益。

注:此ssh非彼SSH(Struts+Spring+Hibernate)

在Java中,我们可以通过Runtime去执行一些OS的命令,如:

String[] shell  =   new  String[]  " /bin/sh " " -c " " ls -l " } ;
Process p 
=  Runtime.getRuntime().exec(shell);

通过在Linux上执行 ssh --help命令,
usage: ssh [-1246AaCfgKkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]
           [-D [bind_address:]port] [-e escape_char] [-F configfile]
           [-i identity_file] [-L [bind_address:]port:host:hostport]
           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
           [-R [bind_address:]port:host:hostport] [-S ctl_path]
           [-w local_tun[:remote_tun]] [user@]hostname [command]
不难发现,ssh命令中并不能带密码。

如果不需要登录时,我们可以用这样的方式来执行:

String[] shell  =   new  String[]  " /bin/sh " " -c " " ssh root@192.168.1.5 ls -l " } ;
Process p 
=  Runtime.getRuntime().exec(shell);

但是事情往往并不是我们想象的如此简单,绝大部分的客户是不能允许他们的Linux中还存在一个不需要密码就能执行任何命令的帐户的。那么,在Java中就没有任何办法通过ssh登录来执行一些命令吗?

不慌,先来Google一下,从一些网上别人请教的代码的蛛丝蚂迹中,发现了JSch (http://www.jcraft.com/jsch/) ,这东东还真是不错,来,我们先看看其官方的简介:

JSch is a pure Java implementation of SSH2.
JSch allows you to connect to an sshd server and use port forwarding, X11 forwarding, file transfer, etc., and you can integrate its functionality into your own Java programs. JSch is licensed under BSD style license. 

这东东支持像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();

    }

看看,是不是挺简单了。

别忘了,由于这是Pure Java program,还有一个优点就是,这样的程序不依赖于OS,可以直接在Windows或者其它OS上运行。

对了,执行这个需要RSA的Key文件,示例如下:
192.168.1.4 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsoINy5sLnrzYCTKBh2UrsqHd62dnnimCZtvq8ojTYt7NcAjjtW2FqmFNO+5x/mTwyY+ssoP5SganxDYs3G016aPZDQdGVZMn/08IsB7QEIAXEVHtgGIGuLqsdMUBBIxV7KI6BK+OWVwv277tBOgqvPcgeEacviFZb2lZhWr8hvR2pTrPFBLr+UELejm/Nnf9qWDBjDj/d2o8+ReSwN8dzNJIiFyWdboyUCZfHhxNgiGANFx22gC4lM+Wk8gkASo/QYDvoUwLFrAJoMdsw0d4pn34bQ0mspaaWy4N0+zrNCPcl8D0Q1RrAjfYfOiZOSTnxabJ2DLijuq7UgFbn2ESMw==
附:产生此文件的简单方法:可以在Linux中用ssh命令登录一次,这样便在/root/.ssh(假如使用root用户登录到Linux)目录下生成known_hosts文件。
posted on 2008-07-08 23:47 Robin's Programming World 阅读(14350) 评论(4)  编辑  收藏 所属分类: Java

评论:
# re: 纯Java通过SSH执行Linux命令[未登录] 2008-07-09 07:37 | javaread.com
换个思路,是不是可以用webservice或者xml-rpc来解决问题呢  回复  更多评论
  
# re: 纯Java通过SSH执行Linux命令 2008-07-09 08:42 | 隔叶黄莺
我原来用的是 j2ssh 组件来用 ssh 协议连接 Linux 做各项系统操作的。  回复  更多评论
  
# re: 纯Java通过SSH执行Linux命令 2008-07-09 09:12 | Robin's Java World
@javaread.com
个人认为,这个思路换得不怎么样了,呵呵。
@隔叶黄莺
谢谢推荐,一会去看看。  回复  更多评论
  
# re: 纯Java通过SSH执行Linux命令[未登录] 2008-07-09 09:59 | javaread.com
如果具体到就是要用通过ssh来操作,也没什么好说的,这也是一种可行的方法。如果换一些场景,情况可能就不是这样了。比如,其实用户不会给开通ssh的,或者想远一些,用ruby,python来远程执行linux命名呢。不过这就想远了,呵呵。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: