微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我的JSch程序无法运行cd命令

如何解决我的JSch程序无法运行cd命令

我已经使用基于Java的JSch库为SSH shell实现了这个简单程序。

程序的工作方式是,首先创建SSHShellBasic实例,然后为该实例运行passwordConnectSSH。成功建立连接后,我将以字符串形式将和命令发送到SSHExec,如下所示:

shell1.SSHExec(pwd); //where shell1 is the current instance of my SSH shell

现在,这对于pwdls之类的命令非常有用。但是,我无法cd进入任何文件夹或mkdir。我不明白为什么。另外,我也没有从shell中得到错误。这是因为我不接受STDERR吗?如果是这样,我该如何实现?

这是我的代码供参考:

import com.jcraft.jsch.*;
import java.io.InputStream;

public class SSHShellBasic extends Thread
{

    String hostname,username,password;
    int portNumber;
    TextArea textArea_terminalOut;
    protected String terminalOut;
    Session session;

    public SSHShellBasic(String hostname,String username,String password,String portNumber,TextArea textArea_terminalOut)
    {
        this.hostname = hostname;
        this.username = username;
        this.password = password;
        this.portNumber = Integer.parseInt(portNumber);
        this.textArea_terminalOut = textArea_terminalOut;
        this.terminalOut = "";
    }

    public boolean passwordConnectSSH()
    {
        try
        {
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking","no");
            JSch jsch = new JSch();
            session = jsch.getSession(username,hostname,portNumber);
            session.setPassword(password);
            session.setConfig(config);
            session.connect();
            //System.out.println("Connected");

        } catch (Exception e)
        {
            return false;
        }
        
        return true;
    }

    public void endSession ()
    {
        session.disconnect();
        System.out.println("\n--------------------\nSession terminated.");
    }
    
    public void SSHExec(String command)
    {
        if (command.charat(0) == '\n')
        {
            command = command.substring(1);
        }
        
        try
        {            
            if (command.equals("terminate"))
            {
                endSession();
                return;
            }

            Channel channel = session.openChannel("exec");
            ((ChannelExec) channel).setCommand(command);
            channel.setInputStream(null);
            ((ChannelExec) channel).setErrStream(System.err);

            InputStream in = channel.getInputStream();
            channel.connect();
            byte[] tmp = new byte[1024];

            while (true)
            {
                while (in.available() > 0)
                {
                    int i = in.read(tmp,1024);
                    if (i < 0)
                        break;

                    String output = new String(tmp,i);
                    
                    System.out.println(output);
                }
                if (channel.isClosed())
                {
                    break;
                }
            }

            channel.disconnect();

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

编辑:

此问题已被标记为重复。建议答案有助于解决我的问题。

问题是JSch的exec在独立实例中运行命令。因此,它不会记住上一个命令,因此总是在连接的服务器的认主目录中运行每个命令/脚本。

由于我的程序主要用于执行基本的Shell操作,因此我需要的关键功能是在所选目录中,所以我先在不同的命令中依次输入“ cd”,“ ls”或“ mkdir”。

为此,我这样做是为了使在通道中发送的第一个命令像这样附加一个pwd:

compositeCommand = command.concat("; pwd");

现在我有了工作目录,可以cd进入我的工作目录以用于后续命令:

if (!pwd.equals(""))
        {
            compositeCommand = "cd ".concat(pwd).concat("; ").concat(oldComposite);
        }

无论何时执行cd操作,pwd变量也会被更新:

if (command.indexOf("cd ") != -1)
        {
            compositeCommand = command.concat("; pwd");
            getPwd = true;
        }
        else
        {
            compositeCommand = command;
        }

这是我的解决方法,可以满足我的要求。

如果您知道一个更好的方法(我不使用JSch shell,因为很难将它与JavaFX GUI集成)或任何问题,那么我们将不胜感激。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。