我现在有这样的一个问题,我的项目需要通过java程序用ssh协议连接服务器 然后从数据库读取出指令在服务器
上执行,
我用的是ganymed-ssh2-build210.jar这个包,测试连接成功
但是当执行 cd .. cd / 这样的指令时发现执行无效 因为我在这两个指令后 又加了一个 ls指令做测试
发现 还是在本目录 并没有退回到上目录 这个jar包有一个好处 它可以将正确的执行结果 和错误提示信息 分开接收到
我 发现这两条指令执行是 都没有返回执行结果 (当然 这个是指令正确执行的情况) 可是也没有返回错误的执行结果
 所以我说指令执行无效了;我在想是不是因为这个“..” 还有“/“是java里面需要转义的字符 程序将这个指令转义为
一个不会执行报错 也不会有执行效果的指令呢 
有没有哪位大侠碰到这样的情况?
我贴出我的代码:package com.friendone.broadband.util;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;import org.apache.commons.io.IOUtils;import com.friendone.broadband.domain.ExecInfo;
import ch.ethz.ssh2.ChannelCondition;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
public class SshConnect {
  private  Connection conn; 
      /** */ /**  远程机器IP  */ 
     private  String     ip; 
      /** */ /**  用户名  */ 
     private  String     usr; 
      /** */ /**  密码  */ 
     private  String     psword; 
     private  String     charset  =  Charset.defaultCharset().toString(); 
 
     private   static   final   int  TIME_OUT  =   1000   *   5   *   60 ; 
 
      /** */ /** 
     * 构造函数 
     *  @param  param 传入参数Bean 一些属性的getter setter 实现略 
      */ 
      public  SshConnect(ExecInfo param)   { 
         this .ip  =  param.getIp(); 
         this .usr  =  param.getUser(); 
         this .psword  =  param.getPassword(); 
    } 
 
      /** */ /** 
     * 构造函数 
     *  @param  ip 
     *  @param  usr 
     *  @param  ps 
      */ 
      public  SshConnect(String ip, String usr, String ps)   { 
         this .ip  =  ip; 
         this .usr  =  usr; 
         this .psword  =  ps; 
    } 
 
      /** */ /** 
     * 登录 
     *  
     *  @return 
     *  @throws  IOException 
      */ 
      private   boolean  login()  throws  IOException   { 
        conn  =   new  Connection(ip); 
        conn.connect(); 
        return  conn.authenticateWithPassword(usr, psword); 
    } 
 
      /** */ /** 
     * 执行脚本 
     *  
     *  @param  cmds 
     *  @return 
     *  @throws  Exception 
      */ 
      public   List<ExecInfo> exec(String cmds)  throws  Exception   { 
     List<ExecInfo> list= new ArrayList<ExecInfo>();
        InputStream stdOut  =   null ; 
        InputStream stdErr  =   null ; 
        String outStr  =   "" ; 
        String outErr  =   "" ; 
         int  ret  =   - 1 ; 
          try { 
              if  (login())   { 
                 //  Open a new {@link Session} on this connection 
                 
                 //  Execute a command on the remote machine. 
                 String[] cmdarrays=cmds.split(";");
                 for(int i=0;i<cmdarrays.length;i++){
                  
                  Session session  =  conn.openSession(); 
                  ExecInfo exec=new ExecInfo();
                  session.execCommand(cmdarrays[i]);
                  
                  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); 
                     
                     System.out.println( " outStr= "   +  outStr); 
                     System.out.println( " outErr= "   +  outErr); 
                     
                     ret  =  session.getExitStatus(); 
                     if(ret==0){
                      exec.setState("0");
                     }else{
                      exec.setState("1");
                     }
                     
                     if(outStr!=null&&!outStr.equals("")){
                      exec.setReturnstr(outStr);
                     }else if(outErr!=null&&!outErr.equals("")){//如果执行出现错误 那么将跳出循环 不再执行之后的指令
                      exec.setReturnstr(outErr);
                      list.add(exec);
                      break;
                     }else {
                      if(ret==0){
                      exec.setReturnstr("执行成功");
                      }else{
                      exec.setReturnstr("执行失败");
                      }
                     }
                     
                     list.add(exec);
                     if(session!=null){
                      session.close();
                     }
                     if(stdOut!=null){
                      IOUtils.closeQuietly(stdOut);
                     }
                     if(stdErr!=null){
                      IOUtils.closeQuietly(stdErr);
                     }
                    
                 }
             }else{ 
                 throw   new  Exception( " 登录远程机器失败 "   +  ip);  //  自定义异常类 实现略 
             } 
         }finally{ 
           if  (conn  !=   null ){ 
                conn.close(); 
           } 
           if(stdOut!=null){
            IOUtils.closeQuietly(stdOut);
           }
           if(stdErr!=null){
            IOUtils.closeQuietly(stdErr);
           } 
        } 
         return  list; 
    } 
 
      /** */ /** 
     *  @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)); 
        } 
         return  sb.toString(); 
    } 
 
      public   static   void  main(String args[])  throws  Exception   { 
       SshConnect exe  =   new  SshConnect( "192.168.1.200" ,  "root" ,  "one#098" ); 
         //  执行指令
         System.out.println(exe.exec( "ls" )); 
     } 
}main函数的测试执行指令”ls“ 可以执行 如果再加一个"cd .." 再ls 这个结果还是不变,我用客户端连接服务器测试这个
cd .. 指令是有效执行的
太奇怪了 望各位能帮我解决解决~

解决方案 »

  1.   

    你的命令组装写法不对,应该是 “cd ..&&ls”,用“&&”拼接一条命令中的多个shell脚本。
      

  2.   

    多加个\n表示回车   eg:cd .. \n  ls 
      

  3.   

    ganymed这个jar包,每次只能执行一条命令,如果一条命令执行了没有关闭,再去执行第二条则会throw new IOException("A remote execution has already started.");所以如果需要执行多条命令,则把多条命令柔和为1条命令,命令之前用回车\n连接,这样就可以成功执行,拿到所有的控制台输出内容