2

I am fairly new to java and now I want to use java to run SSH over windows command.

Here is the code i created,

Process pr1 = Runtime.getRuntime().exec("cmd /k" + "ssh root@host" + "&&" + "passwd" );
Process pr = Runtime.getRuntime().exec("ls");
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line=null;

while((line=input.readLine()) != null)
    System.out.println(line);

I was always given the error :

java.io.IOException: Cannot run program "ls": CreateProcess error=2, The system cannot find the file specified

Can anybody help me on this?

Balázs Édes
  • 13,452
  • 6
  • 54
  • 89
user1672190
  • 159
  • 2
  • 3
  • 6
  • 2
    It seems like you're trying to execute `ls` on a windows machine... it won't execute on the remote machine if that's what you're expecting. – Tudor Sep 14 '12 at 18:31
  • Instead you should find a way to write `ls\n` to the `OutputStream` of the ssh `Process`, but I'm not sure exactly how to do this. Free tip for an answer. You may be better off finding an SSH library for Java though. – Brian Sep 14 '12 at 18:34
  • See [this question](http://stackoverflow.com/questions/995944/ssh-library-for-java). This may be a better approach than doing it manually. – Brian Sep 14 '12 at 18:38

5 Answers5

2

Actually answer maybe quite easy: the problem is that you are executing SSH command and then execute a separate command ls which is sent to Windows console (and not through SSH) so, as you know Windows doesn't have a ls command.

You have to send it to the Process returned by the exec of the SSH command, you can do it by storing the resulting process, retrieve its OutputStream and write commads there. Of course you will have to use its InputStream to fetch the result. The second exec() shouldn't exist at all.

Jack
  • 131,802
  • 30
  • 241
  • 343
  • You switched the streams. You write the command to the `OutputStream` and read the results from the `InputStream` :3 – Brian Sep 14 '12 at 18:35
1

Don't bother with Runtime.exec, use Apache Commons Exec. To apply it to your question it would look like this:

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream);
CommandLine pr1 = CommandLine.parse("cmd /k" + "ssh root@host" + "&&" + "passwd");
CommandLine pr = CommandLine.parse("ls");
DefaultExecutor executor = new DefaultExecutor();
executor.setStreamHandler(streamHandler);

int exitValue = executor.execute(pr1);
exitValue = executor.execute(pr);
Jason Sperske
  • 29,816
  • 8
  • 73
  • 124
  • According to DefaultExecutor JavaDoc, PumpStreamHandler is already used by default so you can probably skip that step of setStreamHandler(); – Rui Marques Aug 28 '14 at 09:43
0

Apart from using JSch (or any other Java SSH implementation), passing the Path via environment variables is likely not to work, since most SSH deamons only accept a small set of variables from the other side (mostly related to localization or terminal type).

As the argument to ssh (or the "command", if using JSch with an ChannelExec) is passed to the remote shell for execution, you could try to define the path in this command (if your default shell is something compatible to the POSIX sh):

PATH=path_needed_toRun_myProg /absPathToMyProg/myProg

Your array for Runtime.exec thus would look like this:

String[] cmd = {"/usr/bin/ssh", "someRemoteMachine",
                "PATH=path_needed_toRun_myProg /absPathToMyProg/myProg"};

If its not hard and strict rule to use Runtime.exec, then try Apache's Exec library...

See this link:

http://commons.apache.org/exec/

Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75
0

You want to written to the process's stdin.

pr.getOutputStream().write("ls\n".getBytes());
John Watts
  • 8,717
  • 1
  • 31
  • 35
  • Since he's on Windows and the other box is some kind of UNIX flavor, what character encoding should be used to turn `ls\n` into bytes? – Brian Sep 14 '12 at 18:36
  • Good question. I doubt there is single correct answer. Given that the characters in question are in 7-bit ASCII many encodings will produce the same bytes. – John Watts Sep 15 '12 at 19:19
0

Please use https://github.com/zeroturnaround/zt-exec . Apache Commons Exec has many shortcomings and you need fairly lot of code to get it right. Everything is explained here: https://zeroturnaround.com/rebellabs/why-we-created-yaplj-yet-another-process-library-for-java/

Martin Vysny
  • 3,088
  • 28
  • 39