Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / Java使用SSH执行UNIX命令问题

这几天项目中要把原来用FTP与TELNET兼容SSH协议,使用com.jcraft.jsch包,也差不多改完,把遇到的问题总结如下: 
 
 
       第一个就是登陆不上,返回异常:auth fail,一开始就登陆不上,郁闷死啦。
 
       不过最后还是在百度找到答案,解决如下:
 
        修改配置文件sshd_config,将PasswordAuthentication设置为 yes (是否需要密码验证)
 
     然后重启。 
 
        然后是要修改unix的IP 地址,发送了修改命令后,就没反应了。不过还好第二天反应过来,IP改变后连接就断开了吧,开始写的程序是要获得返回信息的,一直在等待对方返回。后来就直接发送命令就不管了,然后用修改的新IP连接上去,获得IP,然后比较一个看是否修改了。来个简化的:
 
    /**
   * 只发送执行命令不需要返回结果
   *
   * 修改IP时使用,修改后连接断开,不能正常获得返回信息.
   * @param command
   * @throws Exception
   */
    public void sendCmd(String command) throws Exception
    {        Channel channel = session.openChannel("exec");
        ssh = (ChannelExec) channel;
        ssh.setCommand(command);
        ssh.connect();
     //当然后面得关闭
    }
 
 
 
 然后再连接上去,获得IP比较云云。
 
 
 
      执行shell命令,当然还要获得返回信息的。。。修改IP是执行SFTP上传上去的脚本,自己写的,然后执行完了会echo 返回信息,这没问题,后来要查对方的JDK版本号,直接调unix上的java -version,却什么也不返回了。
 
还是百度,说是返回的信息可能是标准输出,也有可能是错误输出。所以就不能只获得一个输出流了,要这样:
 
     InputStream InputStream = ssh.getInputStream();
        InputStream ErrStream = ssh.getErrStream();        网上我看来还有ssh.getStdout(),但我的怎么就没看到~~
 
来一个简单版本吧:
 
   * 执行命令,返回执行结果
   * @param command 命令
   * @return String 执行命令后的返回
   * @throws IOException
   * @throws JSchException
   */
    public String sendCmd(String command)
            throws Exception
    {
        byte[] tmp = new byte[1024]; //读数据缓存
        StringBuffer strBuffer = new StringBuffer();  //执行SSH返回的结果
             
        Channel channel = session.openChannel("exec");
        ssh = (ChannelExec) channel;
             
        //返回的结果可能是标准信息,也可能是错误信息,所以两种输出都要获取
        //一般情况下只会有一种输出.
        //但并不是说错误信息就是执行命令出错的信息,如获得远程java JDK版本就以
        //ErrStream来获得.
        InputStream InputStream = ssh.getInputStream();
        InputStream ErrStream = ssh.getErrStream(); 
       
        ssh.setCommand(command);
        ssh.connect();
       
        //开始获得SSH命令的结果
        while(true)
        {
       //获得错误输出
            while(ErrStream.available() > 0)
            {
                int i = ErrStream.read(tmp, 0, 1024);
                if(i < 0)
                {
               break;
                }
                   
                strBuffer.append(new String(tmp, 0, i));
            }
           
            //获得标准输出
            while(InputStream.available() > 0)
            {
                int i = InputStream.read(tmp, 0, 1024);
               
                if(i < 0)
                {
               break;
                }
                strBuffer.append(new String(tmp, 0, i));
            }
           
            if(ssh.isClosed())
            {
                logger.info("exit-status: " + ssh.getExitStatus());
                break;
            }
            try
            {
                Thread.sleep(100);
            }
            catch(Exception ee)
            {
            }
        }
 
       
        return strBuffer.toString();
    }
 
 然后对返回信息进行处理云云。
 
基本就这几个问题,其它都很顺利。--------------------------------------分割线 --------------------------------------编写高质量代码 改善Java程序的151个建议 PDF高清完整版 http://www.linuxidc.com/Linux/2014-06/103388.htmJava 8简明教程 http://www.linuxidc.com/Linux/2014-03/98754.htmJava对象初始化顺序的简单验证 http://www.linuxidc.com/Linux/2014-02/96220.htmJava对象值传递和对象传递的总结 http://www.linuxidc.com/Linux/2012-12/76692.htmJava对象序列化ObjectOutputStream和ObjectInputStream示例 http://www.linuxidc.com/Linux/2012-08/68360.htm通过配置SSH深刻理解Puppet的语法及工作机制 http://www.linuxidc.com/Linux/2013-07/87882.htmUbuntu下SSH安装或设置 http://www.linuxidc.com/Linux/2013-07/87368.htm--------------------------------------分割线 --------------------------------------本文永久更新链接地址:http://www.linuxidc.com/Linux/2014-08/105211.htm