I'm no expert, but in my experience, channel.connect needs to be
called after the I/O streams have been set up the way you want. Here is
a method I wrote that separately collects stderr, stdout, and the exit
code. I was unable to figure out how to interleave stderr and stdout
into the same stream. This also doesn't try to display the stream as it
comes in - it only extracts it from the buffered reader after after the
remote command has finished execution:
private ExecResults remoteExec(final String command, final
InputStream in)
throws MyException
{
logger.log(LogLevel.DEBUG, "doing remote execution: " + command);
ExecResults results = new ExecResults();
try {
Channel c = sshSession.openChannel("exec");
((ChannelExec)c).setCommand(command);
// Direct input to command
c.setInputStream(in);
// Direct stderr output of command
InputStream err = ((ChannelExec)c).getErrStream();
InputStreamReader errStrRdr = new InputStreamReader(err,
"UTF8");
Reader errStrBufRdr = new BufferedReader(errStrRdr);
// Direct stdout output of command
InputStream out = c.getInputStream();
InputStreamReader outStrRdr = new InputStreamReader(out,
"UTF8");
Reader outStrBufRdr = new BufferedReader(outStrRdr);
c.connect();
while(true)
{
if(c.isClosed()) {
results.exitCode = c.getExitStatus();
break;
}
try{
Thread.sleep(1000);
} catch(InterruptedException ie) { }
}
c.disconnect();
int ch;
StringBuffer stdout = new StringBuffer();
while ((ch = outStrBufRdr.read()) > -1) {
stdout.append((char)ch);
}
results.stdout = stdout.toString();
StringBuffer stderr = new StringBuffer();
while ((ch = errStrBufRdr.read()) > -1) {
stderr.append((char)ch);
}
results.stderr = stderr.toString();
} catch (Exception e) {
throw new MyException("Error executing remote command '" +
command
+ "'", e);
}
return results;
}
Hope this helps you figure out your usage...
-Dan
On 10/7/10 6:20 AM, Chad Kellerman wrote:
> On Wed, Oct 6, 2010 at 4:49 PM, Baranski, Jack<[email protected]> wrote:
>> Try getting this instead, it works for me:
>>
>> channel.getExtInputStream();
>>
>> Good luck,
>>
>> Jacek
> Thanks for the suggestion. But here is the log info output when all
> Error Stream code is commented:
>
> INFO: Connecting to HOSTNAME port 22
> INFO: Connection established
> INFO: Remote version string: SSH-2.0-OpenSSH_5.2
> INFO: Local version string: SSH-2.0-JSCH-0.1.42
> INFO: CheckCiphers:
> aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256
> INFO: aes256-ctr is not available.
> INFO: aes192-ctr is not available.
> INFO: aes256-cbc is not available.
> INFO: aes192-cbc is not available.
> INFO: arcfour256 is not available.
> INFO: SSH_MSG_KEXINIT sent
> INFO: SSH_MSG_KEXINIT received
> INFO: kex: server->client aes128-ctr hmac-md5 none
> INFO: kex: client->server aes128-ctr hmac-md5 none
> INFO: SSH_MSG_KEXDH_INIT sent
> INFO: expecting SSH_MSG_KEXDH_REPLY
> INFO: ssh_rsa_verify: signature true
> WARN: Permanently added 'HOSTNAME' (RSA) to the list of known hosts.
> INFO: SSH_MSG_NEWKEYS sent
> INFO: SSH_MSG_NEWKEYS received
> INFO: SSH_MSG_SERVICE_REQUEST sent
> INFO: SSH_MSG_SERVICE_ACCEPT received
> INFO: Authentications that can continue: publickey
> INFO: Next authentication method: publickey
> INFO: Authentication succeeded (publickey).
> ls: 0653-341 The file /tmp/bob does not exist.<< this being
> the stderr that I want to grab.
>
>
> Yet when I add just:
>
> InputStream in = ((ChannelExec)channel).getExtInputStream();
> ((ChannelExec)channel).getErrStream();
> or
> channel.getExtInputStream();
>
> and even if I close the inputstream right after instantiating it. I get..
>
> INFO: Connecting to HOSTNAMEport 22
> INFO: Connection established
> INFO: Remote version string: SSH-2.0-OpenSSH_5.2
> INFO: Local version string: SSH-2.0-JSCH-0.1.42
> INFO: CheckCiphers:
> aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256
> INFO: aes256-ctr is not available.
> INFO: aes192-ctr is not available.
> INFO: aes256-cbc is not available.
> INFO: aes192-cbc is not available.
> INFO: arcfour256 is not available.
> INFO: SSH_MSG_KEXINIT sent
> INFO: SSH_MSG_KEXINIT received
> INFO: kex: server->client aes128-ctr hmac-md5 none
> INFO: kex: client->server aes128-ctr hmac-md5 none
> INFO: SSH_MSG_KEXDH_INIT sent
> INFO: expecting SSH_MSG_KEXDH_REPLY
> INFO: ssh_rsa_verify: signature true
> WARN: Permanently added 'HOSTNAME' (RSA) to the list of known hosts.
> INFO: SSH_MSG_NEWKEYS sent
> INFO: SSH_MSG_NEWKEYS received
> INFO: SSH_MSG_SERVICE_REQUEST sent
> INFO: SSH_MSG_SERVICE_ACCEPT received
> INFO: Authentications that can continue: publickey
> INFO: Next authentication method: publickey
> INFO: Authentication succeeded (publickey).
> INFO: Disconnecting from HOSTNAME port 22
> INFO: Caught an exception, leaving main loop due to Socket Closed
> << this is the exception. I don't know whether it should be
> ignored or
>
> Sincerely,
> Chad
>
> ------------------------------------------------------------------------------
> Beautiful is writing same markup. Internet Explorer 9 supports
> standards for HTML5, CSS3, SVG 1.1, ECMAScript5, and DOM L2& L3.
> Spend less time writing and rewriting code and more time creating great
> experiences on the web. Be a part of the beta today.
> http://p.sf.net/sfu/beautyoftheweb
> _______________________________________________
> JSch-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/jsch-users
------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1, ECMAScript5, and DOM L2 & L3.
Spend less time writing and rewriting code and more time creating great
experiences on the web. Be a part of the beta today.
http://p.sf.net/sfu/beautyoftheweb
_______________________________________________
JSch-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jsch-users