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..)
Related
So I am writing a program in java that launches PuTTY from the command line and then I need to be able to switch over to the PuTTY command line once it opens instead of my windows command line. How do I make that switch so I can continues to enter commands in PuTTY?
Basically you have to look into the ProcessBuilder.
The easy part is to use that to start putty. And when you are lucky, you can connect (pipe) the input/output streams into/from that process.
In other words: you will have to wire the parent process; and the child process using those streams; and then you might be able to read all output created by putty and write stuff there.
But that would require that putty prints the "connection" output into its stdout stream; something I very much doubt.
I am trying to call WMIC.EXE from Java to acquire battery information.
Here is the source in JavaX (an extended Java dialect): http://tinybrain.de/1001824
To see the equivalent Java source, look here (just the first 60 lines are important, really).
You can run this program with x30.jar - or by just compiling and running the Java source.
Basically it just produces a process (via a .bat file) and gets its output. The "backtick" function works fine with everything else, including stuff on Windows. Just not with WMIC - everything hangs.
The command run is this:
WMIC Path Win32_Battery Get EstimatedChargeRemaining /Format:List
Running this in the command prompt works fine... just not in Java. Java is weird with subprocesses, really.
Any ideas? Thanks...
I believe this is a duplicate of https://stackoverflow.com/a/13367685/3196753.
Quoting:
You will need to get and close your OutputStream before getting and using your InputStream. That will confirm to the process that you've started that you have finished sending input (in this case, no input) to the process.
p.getOutputStream().close();
Remember that on the Process object, getInputStream() input comes from the output stream of the process, and getOutputStream() output goes to the input stream of the process.
I have a Java application which invokes (using Runtime.getRuntime().exec) a bash script like this:
read -e -p "Are you sure you want to do this? (y/n)? "
echo "$REPLY"
The problem is, I never get the prompt part from the bash script (the "Are you sure..." text).
Is there a way to invoke an interactive bash script from Java so that I can read its output? I need it in order to be able to determine which question I'm being asked by the script (in reality it's a much bigger script than described here).
If I run the process from Java through SSH channel with the -t flag (accent on the t flag, without that it won't work), it works fine. But I would like to avoid having to ssh to myself in order to run the script properly, or more precisely, to read its output properly.
From the bash man page when talking about read:
-p prompt
Display prompt on standard error, without a trailing new‐
line, before attempting to read any input. The prompt is
displayed only if input is coming from a terminal.
So you should make sure you are also capturing stderr if you want to see that message. You can perhaps do this when invoking it from java by adding 2>&1 but I'm not positive that java's invocation will honor that.
If you're using ProcessBuilder to invoke it, you should add a call to redirectErrorStream(true) on the process to get stderr visible via stdout reading.
I have not tried to verify this myself, but this page suggests redirecting stdout for the process to /dev/tty to make it think it's connected directly to the tty for the java process. So you'd add a &>/dev/tty to redirect stdout and stderr to /dev/tty, and hopefully that will get it to show up--though that may have it show up on stderr of the controlling Java process instead of the subprocess. I'm not too sure about that.
If you can't do that, another thing to consider would be to try to modify the script so it does an echo -n "<msg>"; read REPLY so the prompt will be displayed on stdout by echo instead of not at all by read
OK, here' the deal.
As Eric pointed out, prompt is displayed only if input is coming from a terminal, so I needed a pseudo terminal to fool the bash script. I managed to do it by using JPty library.
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.
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...)