How to write in Java to stdin of ssh?

一曲冷凌霜 提交于 2019-12-01 05:58:59

You might try closing the output stream before you expect wc -c to return.

IOUtils.copy(warFileInputStream, deployWarFileStdin);
deployWarFileStdin.close();
IOUtils.copy(deployWarFileStdout, System.out);

warFileInputStream.close();
deployWarFileStdout.close();

Would using Jsch help?

Using JSch would only help if you would be using the setInputStream() and setOutputStream() methods of the channel instead of the IOUtils.copy method, since they manage the copying on a separate thread.

ChannelExec deployWarFile = (ChannelExec)session.openChannel("exec");

deployWarFile.setCommand("/path/to/count-the-bytes");

deployWarFile.setOutputStream(System.out);
deployWarFile.setInputStream(new BufferedInputStream(new FileInputStream(warFile)));

deployWarFile.connect();

(Here you somehow have to wait until the other side closes the channel.)

If you simply replaced the Runtime.exec with opening an ChannelExec (and starting it after getting the streams), the problem would be completely the same, and could be solved by the same solution mentioned by antlersoft, i.e. closing the input before reading the output:

ChannelExec deployWarFile = (ChannelExec)session.openChannel("exec");

deployWarFile.setCommand("/path/to/count-the-bytes");

OutputStream deployWarFileStdin = deployWarFile.getOutputStream();
InputStream deployWarFileStdout = new BufferedInputStream(deployWarFile.getInputStream());
InputStream warFileInputStream = new FileInputStream(warFile);

deployWarFile.connect();

IOUtils.copy(warFileInputStream, deployWarFileStdin);
deployWarFileStdin.close();
warFileInputStream.close();

IOUtils.copy(deployWarFileStdout, System.out);
deployWarFileStdout.close();

(Of course, if you have longer output, you will want to do input and output in parallel, or simply use the first method.)

You probably get an error, but the process hangs because you are not reading the error stream. Taken from the Process JavaDoc

All its standard io (i.e. stdin, stdout, stderr) operations will be redirected to the parent process through three streams (Process.getOutputStream(), Process.getInputStream(), Process.getErrorStream()). The parent process uses these streams to feed input to and get output from the subprocess. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.

So you need to read all of them. Using the ProcessBuilder is probably easier

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!