How do I change directory (cd) with Ganymed SSH API? - java

I must be missing something here, but how do I call something like "cd /root/some/dir/" with Ganymed SSH API?
I created a Connection object
In the first session created, I called "cd /root/some/dir"
In the second session created, I called "ls ." or "./myApp"
That didnt work, because ganymed probably starts each session with its own directory
So do I need to perform both commands on the same session? something like:
session.getStdin().write("cd /root/somedir \n".getBytes());
session.getStdin().write("ls . ".getBytes());
Is that the correct way?? if so, why do we need Session.execCommand?

After doing some research, the only good solution I managed to find is calling the "cd" command within the same code as the "ls" command, like this
session.execCommand("cd /root/somedir ; ls .");
The semicolon will separate the two commands as in any bash code.
In this way, you can query the session's result [session.getExitStatus()] of both the cd and ls commands, which is much better then writing the two commands to session.getStdIn() (after writing to stdin, you kinda loose all the ability to check for exit status...)
Hope this will help the rest
Eyal

According to the Ganymed FAQ (http://www.ganymed.ethz.ch/ssh2/FAQ.html), you are not allowed to send more than one command per Session object you generate. This is how SSH-2 apparently wants you to handle it. Your two options are to either combine the two commands like
session.execCommand("cd /root/somedir ; ls .");
However this wont always work and it get very ugly if you have more than a couple commands. The other way to do this is to open an interactive shell session and write the commands to standard in. This could look something like this:
Session sess = conn.openSession();
sess.requestDumbPTY();
sess.startShell();
OutputStream os = sess.getStdin();
os.write("cd /root/somedir\n".getBytes());
os.write("ls -1\n".getBytes());
os.write("exit\n".getBytes());
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
//TODO
Note the use of the final exit command. Since this is being treated like a terminal window, if you do not exit from the program any loop you have reading the output of the server will never terminate because the server will be expecting more input

OK, I took a quick look on the Ganymed javadoc and although I did not try it myself I assume that you should use method execCommand() of session instead of writing into the STDIN. I am pretty sure that session is connected to remote shell and therefore handles the shell state including current directory, environment variables etc.
So, just do the following:
session.execCommand("cd /root/somedir \n".getBytes());
session.execCommand("ls . ".getBytes());
I hope this will work for you. Good luck.

Related

How to call a bash script from GWT-RPC server (Java)

I want to call a bash script from GWT server
I coded up my first application with GWT/RPC, and I need to call a bash script on the server side (from MyOwnServiceImpl extends RemoteServiceServlet implements MyOwnService).
ProcessBuilder doesn't work
To do that, I confess that I am using java.lang.ProcessBuilder, which is apparently "not supported by GAE" (I just ignored the warning). As it is running on the server side, it seemed to me that it should work anyways. I feel that I am missing something.
Something seems to be preventing the call from being executed, even though the required packages are correctly imported, the binaries are found, the execution doesn't crash. But the call is just not successful (for example even mkdir is not executed on the server).
Related posts weren't much help...
How to execute a Unix shell script via GWT? (does not give a complete answer, and I could not simply comment on the answer)
GWT + ProcessBuilder (mentions precisely the solution I implemented which is not working for me, see above)
Any thoughts on this would be much appreciated, thanks!
In a GWT application without GAE you can use Runtime.getRuntime().exec("some command");
If you want to read out the result of the command, you can use:
Process p = Runtime.getRuntime().exec("A command");
BufferedReader in = new BufferedReader(new InputStreamReader(p.getErrorStream()));
StringBuilder builder = new StringBuilder();
String line = null;
while ((line = in.readLine()) != null) {
builder.append(line + "\n");
}
String result = builder.toString();
If the command above should not work, i guess you have to remove GAE from your project to run a bash script.
you can call bash script with GWT,if your servet side on your computer.
the limit is GAE for secury. no way to cross this limit.

how to implement expect "interact" command using java

I want to implement the expect "interact" command using java. In expect, it's possible to open an ssh session, authenticate and, then, use the "interact" command to give the control back to the user. Is that possible with java? I've tried with expectJ, expect4J and expectForJava but there's little documentation and almost no examples of how to do this. TIA.
Update: for "interact" command reference, please check this out: http://wiki.tcl.tk/3914
"Interact is an Expect command which gives control of the current
process to the user, so that keystrokes are sent to the current
process, and the stdout and stderr of the current process are
returned."
In case anyone is interested, I have added basic interactive loop support to ExpectIt, my own open source Expect for Java implementation (sorry for self-promotion), since version 0.8.
Here is an example of interacting with the system input stream in Java 8:
try (final Expect expect = new ExpectBuilder()
.withInputs(System.in)
.build()) {
expect.interact()
.when(contains("abc")).then(r -> System.out.println("A"))
.when(contains("xyz")).then(r -> System.err.println("B"))
.until(contains("exit"));
System.out.println("DONE!");
}
System.in.close();
These libraries might suit your needs better:
SSHJ
https://github.com/shikhar/sshj
JSCH
http://www.jcraft.com/jsch/

Executing external program in java and passing commands

I have this chess engine Rybka.exe, that i have to execute in java
Here is an example how you run Rybka:
Once you clicked on it, console opens and waits for input.
So then you enter "uci" and you press enter and you wait for it to load (approx. 1 sec) and then you have to enter a few more lines as options and stuff.
The problem is that I don't know how to pass those commands from java to Rybka. The fact is that those commands need to be entered one at a time, because you have to wait for some to execute.
This is how I tried to open it.
Code:
Process p1 = Runtime.getRuntime().exec("Rybka.exe");
This works, because you can see that Rybka.exe is active in task manager, but I don't know how to pass commands to it.
a) how to bind a windows console application with java application?
link provided by the courtesy of Google search query:
https://www.google.pl/search?q=java+binding+console+to+an+app&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a
b) in short:
InputStream is = p1.getInputStream();
OutputStream os = p1.getOutputStream();
(supplied by the obvious http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Process.html)
Have you tried passing parameters/commands as below?
Runtime.getRuntime().exec("Rybka.exe parameter1,parameter2");

Executing linux commands from inside java program

I am trying to create a GUI using java swing. From there I have to run linux system commands. I tried using exec(). But the exec() function is unable to parse the string if it contains single quotes. The code which I have used is as follows-
Process p = Runtime.getRuntime().exec("cpabe-enc pub_key message.txt '( it_department or ( marketing and manager ) )'")
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
But I am getting error when I run the program as--syntax error at "'(".
The same command runs when I write
Process p = Runtime.getRuntime().exec("cpabe-enc pub_key message.txt default")
Please help. Thanks in advance for your help.
Split up the parameters into an array instead, one string for each argument, and use the exec-method that takes as String[] instead, that generally works better for arguments.
Somethign along the lines of:
Runtime.getRuntime().exec(new String[] {"cpabe-enc", "pub_key", "message.txt", "( it_department or ( marketing and manager ) )"});
or whatever what your exact parameters are.
Its because the runtime does not interpret the '(...)' as a single parameter like you intend.
Try using ProcessBuilder instead:
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ProcessBuilder.html
I recently got this kind of problem solved. I was using javaFX to call shell scripts on button click .. which is very much similar to your swing application scenario...
Here are the links hope it might help you...
How to code in java to run unix shell script which use rSync internally in windows environment using cygwin?
Getting error in calling shell script in windows environment using java code and cygwin...!
Happy coding... :)

linux shell and java

I want to send a command to linux shell and get it's response with java.How can i do this?
Have a look at ProcessBuilder - example here.
You should look at the Runtime class, and its exec() family of methods.
It's probably best to explicitly specify that you want to run the command through a shell, i.e. create a command line like "bash -c 'my command'".
Execute a process like this
Runtime.getRuntime().exec("ls");
...then you could get the process input stream and read it with a Reader to get the response
See the Runtime class and the exec() method.
Note that you need to consume the process's stdout/sterr concurrently, otheriwse you'll get peculiar blocking behaviour. See this answer for more information.
I wrote a little class to do this in a very similar question a couple of weeks ago:
java shell for executing/coordinating processes?
The class basically let's you do:
ShellExecutor excutor = new ShellExecutor("/bin/bash", "-s");
try {
System.out.println(excutor.execute("ls / | sort -r"));
} catch (IOException e) {
e.printStackTrace();
}

Categories