java - ssh with jsch: non 'simple' command output trailed with unexpected output combined from fragments of the command in use -
i'm running several commands on ssh using jcraft.jsch channel , see whenever use complicated command (with regexp or using pipes) output of command has unexpected 'prefix' combined fragments of command or entire command fragmented small pieces separated multiple spaces , combined '<' characters here , there...
example 1:
#ls /opt/qb/data2/oscar/process-manager-helper/*/var/core-dump/{2089,2090,2091,2092,2093,2094,2095}.* ger-helper/*/var/core-dump/{20 <2/oscar/process-manager-helper/*/var/core-dump/{208 9,2090,2091,2092,ls: cannot access /opt/qb/data2/oscar/process-manager-helper/*/var/core-dump/2090.*: no such file or directory ls: cannot access /opt/qb/data2/oscar/process-manager-helper/*/var/core-dump/2092.*: no such file or directory ls: cannot access /opt/qb/data2/oscar/process-manager-helper/*/var/core-dump/2094.*: no such file or directory ls: cannot access /opt/data2/oscar/process-manager-helper/*/var/core-dump/2095.*: no such file or directory /opt/qb/data2/oscar/process-manager-helper/0/var/core-dump/2089.20141126-195527.213-00000000-opt.dell.srvadmin.bin.idracadm7.idracadm7.core.gz /opt/qb/data2/oscar/process-manager-helper/0/var/core-dump/2091.20141126-201557.530-00000000-opt.dell.srvadmin.bin.idracadm7.idracadm7.core.gz /opt/qb/data2/oscar/process-manager-helper/0/var/core-dump/2093.20141126-202822.524-00000000-opt.dell.srvadmin.bin.idracadm7.idracadm7.core.gz
example 2:
#du -s --block-size=1 /opt/qb/data2/oscar/process-manager-helper/0/var/core-dump/2089.20141126-195527.213-00000000-opt.dell.srvadmin.bin.idracadm7.idracadm7.core.gz | awk { print $1; } rvadmin.bin.idracad <-195527.213-00000000-opt.dell.srvadmin.bin.idracadm 7.idracadwk <ell.srvadmin.bin.idracadm7.idracadm7.core.gz | awk { print $1; } 86016
here's sample code reproduces (at least on setup):
public static void main(string[] args) throws exception { jsch myconnection = new jsch(); myconnection.setknownhosts("/dev/null"); session mysession = myconnection.getsession("root", "my-host.my-lab.com", 2222); mysession.setpassword("password123"); properties config = new properties(); config.put("stricthostkeychecking", "no"); mysession.setconfig(config); mysession.connect(15000); channel mychannel = mysession.openchannel("shell"); ((channelshell) mychannel).setptytype("exec"); inputstream fromserver = mychannel.getinputstream(); outputstream toserver = mychannel.getoutputstream(); mychannel.connect(); string commandstring = "du -s --block-size=1 /opt/base/dir/eventlog | awk '{ print $1; }'"; toserver.write((commandstring + "\n").getbytes()); toserver.flush(); thread.sleep(5000); stringbuffer result = new stringbuffer(); while (true) { int avail = fromserver.available(); if (avail > 0) { while (avail > 0) { byte[] buf = new byte[avail]; int bytesread = 0; if ((bytesread = fromserver.read(buf)) < 0) { throw new ioexception("connection closed (can't read " + avail + " server) - return value " + bytesread); } (int = 0; < bytesread; i++) { if (buf[i] >= 127 || buf[i] < 9 || (buf[i] >= 14 && buf[i] <= 31) || buf[i] == 11 || buf[i] == 12 || buf[i] == 8) { continue; } result.append((char) buf[i]); } avail = fromserver.available(); } if (result.tostring().trim().endswith("#")) { system.out.println(result); break; } } } }
please advise
channel mychannel = mysession.openchannel("shell"); ((channelshell) mychannel).setptytype("exec"); [...] string commandstring = "du ..."; toserver.write((commandstring + "\n").getbytes());
you're opening shell channel, used interactive sessions. you're writing command string channel's input stream, emulates typing characters of command. way of running commands work, remote system going behave if interactive terminal session. in particular, remote shell may print command prompts, , remote pty may echo text program "typing". think that's happening you--the output of command you're running being mixed command prompts , character echo.
you should consider using channelexec
run remote commands instead of channelshell
. channelexec, remote system directly invokes command (instead of invoking shell , letting feed command shell's input). channel closes when command exits, , shouldn't bothered character echo or command prompts.
jsch has channelexec example. code this:
channelexec chan = mysession.openchannel("exec"); chan.setcommand("du ... | awk ..."); // set input , output streams // request pty if think need 1 chan.connect();
chan.connect()
open channel , launch command on remote system. remote command's standard output can read input stream returned getinputstream()
, , command's standard error can read stream returned geterrstream()
. or can other things streams; see example.
Comments
Post a Comment