【问题标题】:Shell commands are not running using jsch and expcetit library in javaShell 命令未在 java 中使用 jsch 和 expcetit 库运行
【发布时间】:2015-06-28 22:54:45
【问题描述】:

我正在按照以下步骤在 ssh 服务器上运行命令。

  1. 连接到 ssh 服务器
  2. 使用 devpush 命令再次登录到服务器(使用 expectit 库作为用户输入提示)。
  3. 终于使用 jsch 库运行远程命令。

我面临的问题是,我的代码处于无限循环中,它能够登录到 ssh 服务器但无法运行命令。 任何人都可以帮助我,因为我是第一次使用这两个库。

package com.dmotorworks.cdk;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import net.sf.expectit.*;
import net.sf.expectit.matcher.Matchers;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

public class ShellClient {

    public void loginToPabloServer() throws IOException, JSchException{
        String hostname="pablo.dmotorworks.com";
        String username="gaikwasu";
        String password="Nexus@80900";
        final String  endLineStr=" # ";

        JSch jsch = new JSch();     
        Session session = jsch.getSession(username, hostname, 22);
        session.setPassword(password);
        jsch.setKnownHosts("C://Users//gaikwasu//.ssh//known_hosts");

        session.connect();
        System.out.println("Connected");


        Channel channel=session.openChannel("shell");
        channel.connect();

        Expect expect=new ExpectBuilder()
                .withOutput(channel.getOutputStream())
                .withInputs(channel.getInputStream(), channel.getExtInputStream())
                .withEchoOutput(System.out)
                .withEchoInput(System.err)
                .withExceptionOnFailure()
                .build();

        expect.expect(Matchers.contains("-bash-4.1$"));    
        expect.send("devpush\n");
        expect.expect(Matchers.contains("[sudo] password for"));
        expect.send(password+"\n");


        DataInputStream dataIn = new DataInputStream(channel.getInputStream());
        DataOutputStream dataOut = new DataOutputStream(channel.getOutputStream());
        BufferedReader bufferReader= new BufferedReader(new InputStreamReader(dataIn));

        dataOut.writeBytes("cd custom\n");
        dataOut.writeBytes("ls -lrt\n");
        dataOut.flush();

        String line=bufferReader.readLine();
        while(!line.endsWith(endLineStr)) {
               System.out.println(line);
          }

        channel.disconnect();
        session.disconnect();
        expect.close();


    }

    public static void main(String[] args) {
        ShellClient shellClient=new ShellClient();
        try {
            shellClient.loginToPabloServer();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JSchException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

【问题讨论】:

    标签: java shell ssh expect


    【解决方案1】:

    不定式循环的原因很可能是因为 Expect 实例同时在单独的线程中读取输入数据,而您尝试在主线程中读取相同的数据。

    在读取数据之前尝试关闭 Expect 实例。它可能会有所帮助。

    但是,我强烈建议在发送密码后继续使用 Expect 实例。 ExpectIt 可以帮助从远程命令输出中提取信息。例如:

        expect.sendLine(password);
        expect.expect(Matchers.contains("-bash-4.1$"));
        expect.sendLine("cd custom");
        expect.expect(Matchers.contains("-bash-4.1$"));
        expect.sendLine("ls -lrt");
        // the lsResult variable should contain the result of the 'ls -l' command
        String lsResult = expect.expect(Matchers.contains("-bash-4.1$")).getBefore();
        System.out.println(lsResult);
    

    请看this的例子。

    【讨论】:

    • 请评论您的代码。我们会很容易理解。如何获得控制台输出?
    • getBefore 方法返回匹配前的控制台输出。 lsResult 变量应该包含ls -l 命令的结果,
    • 谢谢阿列克谢。我无法实现sudo -i。我会开始一个新的问题。你能看看吗? stackoverflow.com/questions/31477489/…
    猜你喜欢
    • 1970-01-01
    • 2013-05-27
    • 2016-01-09
    • 1970-01-01
    • 2012-07-16
    • 2018-09-11
    • 2015-10-16
    • 2012-07-16
    • 1970-01-01
    相关资源
    最近更新 更多