在网上找了该第三方类库,连接到远程linux后默认目录是在/root下,但是现在要执行别的目录下的.sh脚本,直接写该脚本的全路径/opt/ccs/bin/shutdown.sh的话,估计由于该脚本中还包含一些其他的相对路径,无法执行成功。想要先cd到该目录下,然后再./shutdown.sh,但好像该程序每次都会去重新连接linux,所以执行./shutdown.sh时会说找不到该文件。有人能告诉我该怎么处理吗??public class RemoteShellTool {
private Connection conn;
private String ipAddr;
private String charset = Charset.defaultCharset().toString();
private String userName;
private String password;
public RemoteShellTool(){};
public RemoteShellTool(String ipAddr, String userName, String password,
String charset) {
this.ipAddr = ipAddr;
this.userName = userName;
this.password = password;
if (charset != null)
this.charset = charset;
} /**
 *   * 登录远程Linux主机
 *   * @return
 *   * @throws IOException
 */ public boolean login() throws IOException {
conn = new Connection(ipAddr);
conn.connect(); // 连接
return conn.authenticateWithPassword(userName, password); // 认证
} /**
 *   * 执行Shell脚本或命令
 *   * @param cmds 命令行序列
 *   * @return
 */ public String exec(String cmds) {
InputStream in = null;
String result = "";
try {

if (this.login()) {
System.out.println("已连接");
Session session = conn.openSession(); // 打开一个会话
session.execCommand(cmds);
in = session.getStdout();
result = this.processStdout(in, this.charset);
System.out.println("ExitCode: " + session.getExitStatus());
System.out.println(result);
conn.close();
}else {
System.out.println("连接失败");
}
} catch (IOException e1) {
e1.printStackTrace();
}
return result;
}
/**
 *   * 解析流获取字符串信息
 *   * @param in 输入流对象
 *   * @param charset 字符集
 *   * @return
 */ public String processStdout(InputStream in, String charset) {
byte[] buf = new byte[1024];
StringBuffer sb = new StringBuffer();
try {
while (in.read(buf) != -1) {
sb.append(new String(buf, charset));
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
public static void main(String args[]){
RemoteShellTool rt = new RemoteShellTool("192.168.0.41","root","****","utf-8");
String cmds= "/opt/ccs/bin/shutdown.sh ";
rt.exec(cmds);
}
}

解决方案 »

  1.   

    呵呵,这个我也遇到过。shell里面包含这一些如:./ ../之类的相对路径,所以导致执行失败。必须将工作路径转至shell脚本所在路径。我用common-net 2.0包解决过这个问题。或者你在root目录下写个脚本:里面先cd 到你的工作路径,再 sh执行你的shell脚本。不过调用这个root目录下脚本必须用“. 脚本名”来执行。否则工作路径不会被改变。。
      

  2.   


    不知道阁下用commons-net 2.0这个解决该问题,具体是怎么弄的呢,能不能给点代码出来参考下啊,,谢谢啊,
      

  3.   

    看了下你的代码。rt.exec(cmds);exec方法每次都会建立一个连接,在执行完命令后就中断连接。。你把      Session session = conn.openSession(); // 打开一个会话
    放在login里面,然后再增加一个签退的方法。
    这样就能在一个会话里执行多条语句拉~
      

  4.   

    /*我想这就是你想要的telnet吧,既然我下面用的是apache开源包,你下来自己
     *看看能不能自己重写。方法已经给你提供了。
     *要是可以的话结题吧.哈O(∩_∩)
     */
    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.PrintStream;
    import org.apache.commons.net.telnet.TelnetClient;/**
     * 利用apache net 开源包,使用telnet方式获取AIX主机信息
     * @version 1.2
     */
    public class NetTelnet { // Telnet对象
     private TelnetClient telnet = new TelnetClient();
     
     private InputStream in; private PrintStream out; // 提示符。具体请telnet到AIX主机查看
     private String prompt = "$"; // telnet端口
     private String port; // 用户
     private String user; // 密码
     private String password; // IP地址
     private String ip; public NetTelnet(String ip1,String user1,String password1,String port1) {  try {
       // AIX主机IP
       this.ip = ip1;
       this.password = password1;
       this.user = user1;
       this.port = port1;
       telnet.connect(ip, Integer.parseInt(port));
                System.out.println("开始获取输入流...");
       in = telnet.getInputStream();
       out = new PrintStream(telnet.getOutputStream());
       // 登录
       readUntil("login: ");
       write(user);
       readUntil("Password: ");
       write(password);
       readUntil(prompt);
      } catch (Exception e) {
       e.printStackTrace();
      }
     } /**
      * 读取分析结果
      * 
      * @param pattern
      * @return
      */
    public String readUntil(String pattern) {
      try {
       char lastChar = pattern.charAt(pattern.length() - 1);
       StringBuffer sb = new StringBuffer();
       InputStreamReader  br = new InputStreamReader(in); 
       char ch = (char) br.read();
       while (true) {
       System.out.print(ch);
        sb.append(ch);
        if (ch == lastChar) {
         if (sb.toString().endsWith(pattern)) {
          return sb.toString();
         }
        }
        ch = (char)br.read();
       }
      } catch (Exception e) {
       e.printStackTrace();
      }
      return null;
     } /**
      * 写
      * 
      * @param value
      */
     public void write(String value) {
      try {
       out.println(value);
       out.flush();
      } catch (Exception e) {
       e.printStackTrace();
      }
     } /**
      * 向目标发送命令字符串
      * 
      * @param command
      * @return
      */
     public String sendCommand(String command) {
      try {
       write(command);
       return readUntil(prompt);
      } catch (Exception e) {
       e.printStackTrace();
      }
      return null;
     } /**
      * 关闭连接
      * 
      */
     public void disconnect() {
      try {
       telnet.disconnect();
      } catch (Exception e) {
       e.printStackTrace();
      }
     } public static void main(String[] args) {
      try {
       System.out.println("开始执行telnet......");
       NetTelnet telnet = new NetTelnet("10.24.0.17","nmc","NXlt#111","23");
       // 通过aix的命令“查找主机名称”获取数据
       // 命令是 "hostname"
       // 不熟悉命令的参考<<AIX网络管理手册>>
       System.out.println("开始发送hostname命令");
       String result = telnet.sendCommand("cd /nmc/WCDMA_NP/bin");
       System.out.println("显示结果");
       System.out.println(result);
       result = telnet.sendCommand("pwd");
       System.out.println("显示结果");
       System.out.println(result);
       // 最后一定要关闭
       telnet.disconnect();
      } catch (Exception e) {
       e.printStackTrace();
      }
     }
      

  5.   

    一个session可以多次执行session.execCommand(cmds);吗?
    如果执行多次。流应该怎么处理。如果多次执行那流是不是不要关闭