Hey I have run into the following problem when attempting to build a program in java which executes commands on a remote linux server and returns the output for processing...
Basically I have installed Cygwin with an SSH client and want to do the following:
Open Cygwin,
Send command "user#ip";
Return output;
Send command "password";
Return output;
Send multiple other commands,
Return output;
...etc...
So far:
Process proc = Runtime.getRuntime().exec("C:/Power Apps/Cygwin/Cygwin.bat");
Works nicely except I am at a loss as to how to attempt the next steps.
Any help?
The quick way: Don't go through cygwin. Pass your login info and commands as arguments to ssh.
A better way: Install and use the open source and very mature Sun Grid Engine and use its DRMAA binding for Java to exec your commands. You might also consider switching to a scripting language (yours is a very script like task). If you do DRMAA has Perl, Ruby and other bindings as well.
You could also use Plink:
Download here
There is a good set of instructions link here
You can use a command like:
plink root#myserver -pw passw /etc/backups/do-backup.sh
Use a ssh implementation in java. I used Ganymede a couple of years ago, there are perhaps better alternatives now. (?)
Using Ganymede, you will get an input stream to read from, and an output stream to write to.
You can create a LineInputReader on the input stream and use that to read Strings representing the output from the remote server. Then use a regexp Pattern/Matcher to parse responses.
Create a PrintWriter on the output stream and use println() to send your commands.
Its simple and actually quite powerful (if you know regexp... It might require some trial and error to get it right...)
Related
I have a use case where in I have to connect to a CLI and execute commands in that CLI using java. Usually without using java, I do it by opening a linux terminal and connecting to other CLI and execute commands there. I have to implement the same using Java. I am able to run the commands on the linux terminal using Runtime.getRuntime().exec(). But, I need some help in executing the commands after connecting to a particular CLI from linux terminal using Java
I think you are asking how to make use of pseudo-terminals. I was going to warn you this was likely more complicated than you were bargaining for, but a short search showed the pty4j library which may be of help.
When you run an external program using Runtime.exec(), it returns a Process object that you can use to interact with the running process. That object has a getOutputStream() method that you can use to send commands to the process, and, getInputStream() and getErrorStream() methods that you can use to read messages produced by the process.
The Java program has to launch few prorams that are launched using a command promt(one of them is nginx). How could I handle and send commands to the program from my Java application?
I found this library http://commons.apache.org/proper/commons-cli/usage.html But I'm not sure how it helps..
I do NOT need code. I need an explanation on how things like these work.
Well keep in mind its never a nice solution.
You act like you would be on a command line so you execute Commands like you would on the shell. And does always depend on your platform.
You said you don't want code, I will give it to you anyway ;)
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("service nginx start");
That is done with plan java.
I highly advise you to use a script language for that. Thats just not Java.
additional info:
One thing to remember is to use the streams on process to send input and check output (from Process class)
abstract InputStream getErrorStream()
Returns the input stream connected to the error output of the subprocess.
abstract InputStream getInputStream()
Returns the input stream connected to the normal output of the subprocess.
abstract OutputStream getOutputStream()
Returns the output stream connected to the normal input of the subprocess.
If you need to execute shell commands, this can be achieved like so (This example uses bash as the executing process)
Process p = Runtime.getRuntime().exec(new String[]{"bash","-c","my_script.sh"});
You'll have to write your own script for this, but you don't even have to put it in a file. If you wanted to give user-like input to a command, keep in mind that you can pipe in the result of an echo to a command and it will act as a user typing that command. e.g
echo 1234 | pinTaker.sh;
This will effectively "type in" 1234 to the pinTaker script. This can also be used for things like typing in a password for ssh (Though this is not a good idea, it's a good example..)
I'm writing a shell script that's supposed to do the following.
- run a Java application that produces output
- run a shell command that produces output
- gather both outputs and send them out in an email
I have control of the source code of all the steps above.
Is there a best practice in gathering output from different sources? Should I redirect everything to a single temp file? Should I write different output to different files then concatenate them? What are the pros and cons of each approach?
If you don't worry about using just Java you could use the Runtime class to execute the shell command withing java (through exec) command, this will return you a Process object on which you have either getInputStream and getOutputStream so you will then be able to process the output of both the Java program and the shell command inside just one place and do whatever you want (keeping it in memory and directly send it by redirecting the outputstream to the inputstream of what you use to send the mail, with another exec) or saving it or whatever.
I'd favor using a second wrapper script which
calls the java program
calls the shell script
Captures output to a single file
reformats that output
suitable for mailing out Actually
does the mailing
Assuming you are using a unix shell, mailing/formatting and shell script calls are much simpler from the command line.
I am looking for a way to check the state of a windows service through Java. From some basic search through Google and here it sounds like Java has no api to query the Windows Services.
On the Windows command prompt running: sc \some_host_name query "serviceName"
gets me the info i want. Now i want to be able to run that in a Java program and be able to parse the output.
Any one know of a way to run a Windows command through Java?
Sounds like you need the Java 5+ ProcessBuilder.
A quick example (based the above documentation)
To start a process running:
Process p = new ProcessBuilder("sc", "\\some_host_name", "query", "serviceName").start();
The Process class provides methods to get the output (and error) stream from the process - it's standard stream handling from there.
The pre-Java 5 way of doing this was Runtime.exec(). I haven't actually used ProcessBuilder on Windows myself, drop a comment if you have problems?
All,
Our server is running Java 1.5 and I am having difficulty trying to mask user input from the command line. I am executing a jar file (java -jar my.jar) and am working through command line prompts via printlns. I cannot use Java Console.
Thanks
The best approach would be to use Java 6's Console readPassword() method. Since you mentioned that you are using Java 5, that is not an option. A lot of Java 6 utilities have been backported to Java 5. I have not found anyone who has done it for this class though.
This site has a good article on how to do it using Java 5. http://www.devdaily.com/java/edu/pj/pj010005/. Basically they wrap System.in with an InputStreamReader and read a line.
On a Unix system? You could try running the system program stty with argument -echo before reading the program and the program stty echo afterwards.
ProcessBuilder pb = new ProcessBuilder("stty", "-echo");
pb.start().waitFor();
// Read the password here
pb = new ProcessBuilder("stty", "echo");
pb.start().waitFor();
Note that I have not tried this! Some stty programs are happy with it and some aren't (those that aren't need their stdin to come from /dev/tty to work right...)
Here is an interesting article: http://java.sun.com/developer/technicalArticles/Security/pwordmask/
edit now that I re-read that, I think their command-line "solution" is really stupid. What we've got in our application is an auxiliary program to do that, one that understands how to mask input according to the OS (Linux, Windows, whatever). The Java code listens for commands on a socket, and the front-end password reader gets the password and anything else needed, then sends commands to the Java code.