简体   繁体   中英

JSch: var set in one command not visible by the next (same Session)

I am able to successfully connect to a remote Unix host from Java using JSch and run some basic commands and view files etc.

The problems start with setting the environment... When i export a var in one command, it is not visible in the next as though they run in separate shells. What I would like to do is emulate multiple commands running in the same shell.

Here is my executeCommand method. It takes a previously created com.jcraft.jsch.Session created by openHostSession (below):

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

    }

here is 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;
    }

client code

cmd = "export XVAR=abc";
SshUtil.executeCommand(sess, cmd, System.out);

cmd = "echo $XVAR";
SshUtil.executeCommand(sess, cmd, System.out);

outputs:

About to execute <export XVAR=abc>
exit-status: 0
About to execute <echo $XVAR>

exit-status: 0

I can see system-level env vars, eg:

cmd = "echo $SHELL";
SshUtil.executeCommand(sess, cmd, System.out);

returns

About to execute <echo $SHELL>
/bin/ksh

exit-status: 0

Similar thing happens when I source my .profile ( cmd = ". ./.profile";) , the vars set within .profile are not visible in the next command. The commands share the same Session but each opens its own Channel. I tried sharing Channels but that didn't do.

This is how the exec channel works. It executes a single command against the SSH server and each command execution is independent of the next. It's like you did something like:

# ssh machine 'VAR=tmp; echo $VAR'
foo
# ssh machine 'echo $VAR'

Those are two separate command executions so the setting of the environment variable VAR will not exist in the context of the second command (since they are two shells that get executed). If you want to stream a series of commands with JSch, you should probably look into the ChannelShell class. You can utilize that by calling:

ChannelShell chnl = (ChannelShell)sess.openChannel("shell");

This will open up a long-standing interactive shell where you can execute a series of commands and have the result of the first command impact the second command. It does add quite a bit of complexity to use this though so it's not a drop-in replacement for "exec". I'd recommend checking out the various examples that come with the JSch distribution. Many of them use the openChanell("shell") technique and they might help you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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