简体   繁体   English

Shell命令未在Java中使用jsch和expcetit库运行

[英]Shell commands are not running using jsch and expcetit library in java

I am following below steps for running commands on ssh server. 我正在按照以下步骤在ssh服务器上运行命令。

  1. Connecting to ssh server 连接到SSH服务器
  2. Using devpush command again logging to server (using expectit library for user input prompt). 再次使用devpush命令登录到服务器(使用Expectit库作为用户输入提示)。
  3. Finally running remote commands using jsch library. 最后使用jsch库运行远程命令。

The issue I am facing is that, my code is going in infinite loop it is able to login to ssh server but not able to run the commands. 我面临的问题是,我的代码正在无限循环中,它能够登录到ssh服务器,但无法运行命令。 Can any one please help me on this as I am using both the libraries for first time. 我第一次使用这两个库时,任何人都可以帮忙吗?

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();
        }
    }
}

Most probably the cause of the infinitive loop is because the Expect instance reads the input data in a separate thread at the same time while you are trying to same data in the main thread. 导致不定式循环的原因很可能是因为Expect实例在尝试在主线程中读取相同数据时同时读取了单独线程中的输入数据。

Try to close the Expect instance before reading the data. 在读取数据之前,请尝试关闭Expect实例。 It may help. 这可能会有所帮助。

However, I strongly recommend to keep using the Expect instance after the sending password. 但是,我强烈建议在发送密码后继续使用Expect实例。 ExpectIt can help with extracting the information from the remote command output. ExpectIt可以帮助从远程命令输出中提取信息。 For example: 例如:

    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);

Please take a look at this example. 请看这个例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM