当前位置: 首页 > 知识库问答 >
问题:

JSch 问题 - 无法检索完整的命令输出 [已关闭]

公冶森
2023-03-14

< b >想改进这个问题?通过编辑此帖子添加详细信息并澄清问题。

我正在使用JSch连接到SSH并执行命令。其中一个命令给出了一个很大的输出。在终端中,如果您执行命令,则必须按回车键才能看到整个输出。使用 JSch 我无法检索整个输出。

当我使用交互式终端登录时,命令输出在填充屏幕后停止,并等待Enter

代码取自如何在String中获取jsch shell命令输出:

public class SshConnectionManager {

    private static Session session;
    private static ChannelShell channel;
    private static String username = "";
    private static String password = "";
    private static String hostname = "";


    private static Session getSession(){
        if(session == null || !session.isConnected()){
            session = connect(hostname,username,password);
        }
        return session;
    }

    private static Channel getChannel(){
        if(channel == null || !channel.isConnected()){
            try{
                channel = (ChannelShell)getSession().openChannel("shell");
                channel.connect();

            }catch(Exception e){
                System.out.println("Error while opening channel: "+ e);
            }
        }
        return channel;
    }

    private static Session connect(String hostname, String username, String password){

        JSch jSch = new JSch();

        try {

            session = jSch.getSession(username, hostname, 22);
            Properties config = new Properties(); 
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.setPassword(password);

            System.out.println("Connecting SSH to " + hostname + " - Please wait for few seconds... ");
            session.connect();
            System.out.println("Connected!");
        }catch(Exception e){
            System.out.println("An error occurred while connecting to "+hostname+": "+e);
        }

        return session;

    }

    private static void executeCommands(List<String> commands){

        try{
            Channel channel=getChannel();

            System.out.println("Sending commands...");
            sendCommands(channel, commands);

            readChannelOutput(channel);
            System.out.println("Finished sending commands!");

        }catch(Exception e){
            System.out.println("An error ocurred during executeCommands: "+e);
        }
    }

    private static void sendCommands(Channel channel, List<String> commands){

        try{
            PrintStream out = new PrintStream(channel.getOutputStream());

            out.println("#!/bin/bash");
            for(String command : commands){
                out.println(command);
            }
            out.println("exit");

            out.flush();
        }catch(Exception e){
            System.out.println("Error while sending commands: "+ e);
        }

    }

    private static void readChannelOutput(Channel channel){

        byte[] buffer = new byte[1024];

        try{
            InputStream in = channel.getInputStream();
            String line = "";
            while (true){
                while (in.available() > 0) {
                    int i = in.read(buffer, 0, 1024);
                    if (i < 0) {
                        break;
                    }
                    line = new String(buffer, 0, i);
                    System.out.println(line);
                }

                if(line.contains("logout")){
                    break;
                }

                if (channel.isClosed()){
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception ee){}
            }
        }catch(Exception e){
            System.out.println("Error while reading channel output: "+ e);
        }

    }

    public static void close(){
        channel.disconnect();
        session.disconnect();
        System.out.println("Disconnected channel and session");
    }


    public static void main(String[] args){
        List<String> commands = new ArrayList<String>();
        commands.add("ls -l");

        executeCommands(commands);
        close();
    }
}

共有1个答案

商迪
2023-03-14

通常不应使用“shell”通道来自动执行命令。

“shell”通道旨在实现交互式shell会话。

因此它请求PTY(伪终端),它具有对人类友好,但对机器不友好的副作用,会破坏您的代码。

请改用“exec”通道。

请参见在Java中使用JSch exec从ArrayList执行命令列表

如果您出于某种原因需要或想要使用“shell”通道(但不要这样做,它会咬你一口),请确保您调用了< code >。setPty(false)在< code >之前。连接:

channel = (ChannelShell)getSession().openChannel("shell");
channel.setPty(false);
channel.connect();

旁注:

    <李>《<代码>》#!/bin/bash"纯属扯淡。shell忽略所有以< code>#(它是comment)开头的命令。发也没什么意义。 < li >不要使用< code > stricthostkey checking = no 。参见JSch SFTP安全with session . set config(" StrictHostKeyChecking "," no ");.
 类似资料:
  • 问题内容: 我正在使用JSch连接到SSH并执行命令。其中一个命令给出了很大的输出。在终端中,如果执行命令,则必须按Enter键才能查看整个输出。使用JSch,我无法检索整个输出。 当我使用交互式终端登录时,命令输出在填充屏幕后停止并等待。 该代码取自 如何在String中获取jschshell命令输出: 问题答案: 通常,您不应使用“ shell”通道来自动执行命令。 “外壳”通道旨在实现交互式

  • 问题内容: 我有以下代码: 试图从阅读器中读取内容已挂起。我该如何解决?我该如何寻找正在发生的事情? 问题答案: 在等待命令完成的同时,必须连续读取输出。否则,如果命令产生足够的输出以填充输出缓冲区,则该命令将挂起,等待缓冲区被消耗,这将永远不会发生。这样您就陷入僵局。 以下示例在监视命令状态的同时连续读取stdout和stderr。它基于官方的JSch 示例 (仅添加了stderr的阅读)。 如

  • 谁能帮我修一下吗?我正在尝试在colab中安装pyenchant,以便在单词拼写错误时执行可能的建议。我想使用。这就是我所尝试的; 但它输出以下错误; 我的想法是得到一些可能的建议,如果一个词是错的,我计划做以下几点 有人能建议我如何做到这一点吗?我正在研究colab。请帮助我如何在colab中安装,或者在单词错误时我可以获得任何其他可能的建议。

  • 我们如何在docker history命令输出的第三列(由创建)中看到完整命令? 第三列(CREATED BY)是命令的缩写,这使得重建原始Dockerfile变得困难。是否可以在第三列中获得完整的命令? 感谢阅读。

  • 看来是从到达这里的,我也在我的项目中使用它 但这只是一个假设。问题可能出在别的地方。有什么想法吗?

  • 本文向大家介绍Windows cmd命令行输入输出重定向问题,包括了Windows cmd命令行输入输出重定向问题的使用技巧和注意事项,需要的朋友参考一下 最近学校的网比较搓,DNS天天挂,出口带宽天天堵,NAT后的总出口带宽也才4MB/s(来源:360测速),唉,不亲身体会鬼才知道一堆人共享这个带宽是什么感觉。 废话不多说了,在Unix下重定向用着感觉很high,现在想把win下的nslooku