我能够使用JSch成功地从Java连接到远程Unix主机,并运行一些基本命令和查看文件等。
问题从设置环境开始..。当我在一个命令中导出var时,它在下一个命令中是不可见的,就好像它们在单独的shell中运行一样。我想要做的是模拟运行在同一个shell中的多个命令。
这是我的executeCommand方法。它采用openHostSession以前创建的com.jcraft.jsch.Session (如下所示):
    public static void executeCommand(Session sess, String cmd, PrintStream pstream)
    {
        System.out.println("About to execute <" + cmd + ">");
        try
        {
            ChannelExec chnl = (ChannelExec)sess.openChannel("exec");     
            chnl.setInputStream(null);      
            chnl.setErrStream(System.err);  
            chnl.setCommand(cmd);      
            InputStream in = chnl.getInputStream();      
            chnl.connect();      
            byte[] tmp=new byte[1024];      
            while(true)
            {        
                while(in.available() > 0)
                {          
                    int i = in.read(tmp, 0, 1024); 
                    if(i < 0) break;          
                    pstream.print(new String(tmp, 0, i));        
                }        
                if(chnl.isClosed())
                {          
                    pstream.println("exit-status: " + chnl.getExitStatus());   
                    break;        
                }        
                try
                {
                    Thread.sleep(1000);
                }
                catch(Exception ee){}      
            }      
            chnl.disconnect();
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }这是openHostSession
public static Session openHostSession(String host, String user, String passwd)
    {
        JSch jsch=new JSch();
        Session rslt = null;
        try
        {
            rslt = jsch.getSession(user, host, 22);
            rslt.setConfig("StrictHostKeyChecking", "no"); 
            rslt.setPassword(passwd);
            rslt.connect(30000);   
        }
        catch(JSchException jschEx)
        {
            jschEx.printStackTrace();
        }
        return rslt;
    }客户端代码
cmd = "export XVAR=abc";
SshUtil.executeCommand(sess, cmd, System.out);
cmd = "echo $XVAR";
SshUtil.executeCommand(sess, cmd, System.out);产出:
About to execute <export XVAR=abc>
exit-status: 0
About to execute <echo $XVAR>
exit-status: 0我可以看到系统级env,例如:
cmd = "echo $SHELL";
SshUtil.executeCommand(sess, cmd, System.out);返回
About to execute <echo $SHELL>
/bin/ksh退出-状态:0
类似的事情发生在我的.profile (cmd = ". ./.profile";),在.profile中设置的vars在下一个命令中不可见)时发生。这些命令共享同一个会话,但每个命令都打开自己的通道。我试过分享频道,但没成功。
发布于 2012-10-19 18:39:19
这就是执行通道的工作方式。它对SSH服务器执行一个命令,每个命令的执行都独立于下一个命令。就像你做了这样的事:
# ssh machine 'VAR=tmp; echo $VAR'
foo
# ssh machine 'echo $VAR'这是两个单独的命令执行,因此环境变量VAR的设置将不存在于第二个命令的上下文中(因为它们是被执行的两个shell)。如果您想使用JSch流一系列命令,那么您可能应该查看ChannelShell类。您可以通过调用:
ChannelShell chnl = (ChannelShell)sess.openChannel("shell");这将打开一个长期的交互式shell,您可以在其中执行一系列命令,并产生第一个命令的结果,即第二个命令。不过,使用它确实增加了相当大的复杂性,因此它并不是"exec“的替代物。我建议查看JSch发行版附带的各种示例。他们中的许多人使用openChanell("shell")技术,他们可能会帮助您。
https://stackoverflow.com/questions/12980041
复制相似问题