【问题标题】:JSch - command not being sent to shell?JSch - 命令未发送到外壳?
【发布时间】:2015-02-17 22:48:14
【问题描述】:

我正在开发一个项目,以使用 JSch 在远程服务器的屏幕上重新启动某些内容...但是我遇到了问题。它将 100% 的时间发送前 2 个命令,但仅在某些时候发送第 3 个命令。任何帮助将不胜感激。

public static void stopServer(String name, String ip, String passwd)
{
    try {
        Session session = Main.jsch.getSession("user",ip,22);
        session.setConfig("StrictHostKeyChecking", "no");
        session.setPassword(passwd);
        session.connect();
        Channel channel = session.openChannel("shell");
        channel.connect();
        ChannelShell cs = (ChannelShell) channel;
        cs.setPty(true);
        DataInputStream dataIn = new DataInputStream(channel.getInputStream());
        PrintStream dataOut = new PrintStream(channel.getOutputStream());
        dataOut.println("screen -x "+name);
        dataOut.flush();
        dataOut.println("stop");
        dataOut.flush();
        String line = dataIn.readLine();
        System.out.println(line);
        while(true) {
            line = dataIn.readLine();
            System.out.println(line);
            if(line.contains("\"quit\""))
            {
                break;
            }
        }
        TimeUnit.SECONDS.sleep(1);
        dataOut.println("quit");
        dataOut.flush();
        System.out.println("Shutdown");
        dataIn.close();
        dataOut.close();
        channel.disconnect();
        session.disconnect();

    }catch(Exception e)
    {
        e.printStackTrace();
    }
}

这会在 100% 的情况下发送 screen -x 'name' 和 stop 从我所看到的情况来看,但 'quit' 命令实际上只在一小部分时间内被控制台发送/理解。任何帮助将不胜感激!

【问题讨论】:

    标签: java jsch


    【解决方案1】:

    我设法以一种不使用 shell 通道的方式解决了这个问题,但它足够可靠,可以正常工作:

    //Start EXEC
                ChannelExec ce = (ChannelExec) session.openChannel("exec");
                ce.setCommand("screen -S " + name + " -X stuff 'quit\n'");
                ce.setInputStream(null);
                ce.setErrStream(System.err);
                InputStream in=ce.getInputStream();
    
                ce.connect();
    
                byte[] tmp=new byte[1024];
                while(true){
                    while(in.available()>0){
                        int i=in.read(tmp, 0, 1024);
                        if(i<0)break;
                        //System.out.print(new String(tmp, 0, i));
                    }
                    if(ce.isClosed()){
                        if(in.available()>0) continue;
                        //System.out.println("exit-status: "+ce.getExitStatus());
                        break;
                    }
                    try{Thread.sleep(1000);}catch(Exception ee){}
                }
                ce.disconnect();
                //STOP EXEC
    

    尽管这不能解决问题的原始思路,但它为我解决了问题。

    【讨论】:

    • 使用“exec”通道肯定更合适可靠。
    【解决方案2】:
    1. 如果在发送“退出”命令之前的某个时间抛出异常,则永远不会发送退出命令。

    2. 如果 while 循环永远不会中断,那么这将阻止“退出” 命令也被发送。

    【讨论】:

    • 我知道它没有抛出异常,也没有卡在 while 循环中,因为 while 之后的打印输出到控制台。
    • @VoidWhisperer 那么远程服务器可能没有正确处理命令?或者服务器可能需要一些时间来处理命令?
    • 这看起来很像 codereview 的答案。你为什么不找个时间过来复习一下?
    猜你喜欢
    • 1970-01-01
    • 2021-03-27
    • 2015-10-19
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多