Runtime.getRuntime().exec() with gpg command not working - java

I have gpg command which encrypts the file
gpg --batch --yes -o abc.csv.gpg -r 'balu shanmukh' -e A2.java
in the above command
--batch
--yes
-o
-r and -e are options
and balu shanmukh is the value.
the command is prepared dynamically and the command prepaed is the above. this command is being exected in commandline but when this command is running from
Runtime.getRuntime().exec(command);
am getting error message
as usage: gpg [options] [filename]
their is no problem with gpg classs path or anything because if i remove the single quote for the value which doesnt have space in between the command is getting executed properly from java.
only the problem when we have space in value . then its mandatory to use quote for value and if i use it . commad is not getting executed properly
I didnt understand the behaviour?
can any one help me to understand this behaviour

Don't use Runtime().exec(), and don't create the command as a single string. Instead, build a ProcessBuilder for your Process, and pass each switch to your command as an argument.
Here's a simple example:
Process process = new ProcessBuilder("gpg", "--foo", "-r", "some_file_name").start();
int exitStatus = process.waitFor();
PS: As others noted, do revisit your questions, and check the answers you think answer your question. People give some effort answering. If you think they helped, vote them up, or check their answer as the one that answered your question.
Good luck and welcome here ;)

Here's a simple example:
Process process = new ProcessBuilder("gpg", "--foo", "-r", "some_file_name").start();
int exitStatus = process.waitFor();
Sorry but that doesnt explain how you pass a single quoted string as an argument.
ie. to pass 'baku' as an argument.
"'baku'" does not work....

Related

how to pass parameter to shell script to use as part of variable filename [duplicate]

This question already has answers here:
How do I parse command line arguments in Bash?
(40 answers)
Closed 4 years ago.
I am trying to programmatically call from my java program a shell script that in turn executes a command depending of the parameter sent.
the command to be executed inside the connectvpn.sh shell script is:
echo myrootpassword | sudo -S /usr/local/Cellar/openvpn/2.3.8/sbin/openvpn --config /usr/local/etc/openvpn/1.opvn
or
echo myrootpassword | sudo -S /usr/local/Cellar/openvpn/2.3.8/sbin/openvpn --config /usr/local/etc/openvpn/2.opvn
and so on from a long list, where the filename number I want to be variable depending on the value of the parameter received
So I want my java program to be able to use always the same shell script but use different .ovpn file depending on the parameter sent.
I believe that on my java program I have to call it something like this:
server_number = 1;
ProcessBuilder pb = new ProcessBuilder("./connectvpn.sh", server_number);
Process proc = pb.start();
What would go in the shell script so that the filename called is variable and for the example shown it uses 1 but other times it uses whatever number is sent as parameter?
Thank you very much!
In the shell script, use $1 to denote the first parameter passed to it.
Fix your java as below,
ProcessBuilder pb = new ProcessBuilder("./connectvpn.sh", String.valueOf(server_number));

Struggling with parameters to Runtime.exec()

I've already checked the many good answers here for the exec() pittfalls, and even read this article http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html but found nothing that helps. I feel like I'm on trial-and-error here without getting anywhere.
I have these two (tested and working on the command line) commands I need to run via .exec():
find <PATH>* -mtime +180 -exec rm {} \;
find <PATH>* -mtime +1 -gzip -q rm {} \;
But no matter how I pass the parameters I always seem to get a different error which doesn't help in telling what is missing. For example: in -exec do I need the {} separated from the argument? Do I need the closing \; in the call to .exec() or not?
My last attempt looks something like:
rt.exec( new String[]{"find", path+"*", "-mtime", "+180", "-exec rm {}", "\\;"} );
rt.exec( new String[]{"find", path+"*", "-mtime", "+1", "-exec gzip -q {}", "\\;"} );
Any help would be appreciated. Thanks.
Run the script in the command line and if it Works just copy that string and pass it to getRuntime.exec(string)
Also you should specify which programm will execute the script, i'm guessing in this case should be cmd.exe
This did the trick:
rt.exec(new String[]{"/bin/sh", "-c", "find "+path+"* -mtime +1 -exec gzip -q {} \\;"});
The interpreter /bin/sh was needed, and the rest of the command can go as single argument to .exec().

Passing pre-escaped command-line arguments to ProcessBuilder

I bumped into this problem today when setting up a local set of communicating programs. Basically one of my applications is sending some data to another, and part of this data is a string containing a command to execute (like you would from the command-line). Let's say, for example:
g++ foo.cc bar.cc -o foobar
is the command sent by my first application. The second application, which receives the command (amongst other things), needs to execute this command after doing some other processing.
Now, at first I thought this would be trivial using a ProcessBuilder:
String exampleCommand = "g++ foo.cc bar.cc -o foobar";
ProcessBuilder builder = new ProcessBuilder(exampleCommand);
builder.start().waitFor();
However this is where the problem occurs.
CreateProcess error=2, The system cannot find the file specified
Okay, no worries I guess I can't just dump the whole thing into the builder. The first part of the command is usually a trivial string so I thought I could probably get away with a split around the first ' ' to separate the program name and arguments.
String exampleCommand = "g++ foo.cc bar.cc -o foobar";
String[] parts = exampleCommand.split(" ", 2);
ProcessBuilder builder = new ProcessBuilder(parts[0], parts[1]);
builder.start().waitFor();
And this brought me a little closer, the g++ file could now be found correctly, however after examining the stderr of g++ I found that the following error had occurred:
g++.exe: error: foo.cc bar.cc -o foobar: No such file or directory
At this point I realised that the ProcessBuilder class must be escaping all arguments passed to it in preparation for the command-line (hence the reason it usually takes arguments as an array of individual arguments rather than just a predefined argument string).
My question is, "Is there any way to pass a raw string of arguments to a ProcessBuilder and say THERE, execute EXACTLY this?"
Because the command comes from another application and is in no way static I can't just break the arguments down into an array beforehand and pass them to the ProcessBuilder constructor properly. The arguments are not so trivial that simply splitting the string around a ' ' will work properly either; arguments might contain spaces escaped with double quotes. For example:
g++ "..\my documents\foo.cpp" bar.cpp -o foobar
Could be a command coming from the application and splitting that string around ' ' and passing it to the ProcessBuilder will result in corrupt arguments.
If there is no proper way to do this can someone please point me to a standalone command line argument parser (in Java) that can turn a command-line string into a valid String[]?
Okay I feel rather foolish now but I achieved my desired result by simply reverting back to the good old Runtime.getRuntime().exec(...). I'll leave the question up in case anyone is as silly as me and find it useful.
String exampleCommand = "g++ foo.cc bar.cc -o foobar";
Runtime sys = Runtime.getRuntime();
sys.exec(exampleCommand);
Easy.
A comment to the Runtime.getRuntime().exec(...) solution:
The Runtime.getRuntime().exec(...) is not good anymore. In java executed on OSX El Capitan, 'Runtime.getRuntime().exec(...)' contains an error that sometimes closes the opened process when the java program exits. It works fine on previous OSX versions. However, ProcessBuilder works on all OSX versions.
(Haven't posted enough to have a enough rep points to make this as a normal comment.)

error while running CRF++ from a java project

I want to call CRF++ toolkit from a java program. I type the following:
Process process = runtime.exec("/home/toshiba/Bureau/CRF++-0.54/.libs/lt-crf_learn /home/toshiba/Bureau/CRF++-0.54/example/atb/template /home/toshiba/Bureau/CRF++-0.54/example/atb/tr_java.data");
process.waitFor();
But, I have the the following error:
CRF++: Yet Another CRF Tool Kit
Copyright (C) 2005-2009 Taku Kudo, All rights reserved.
Usage: /home/toshiba/Bureau/CRF++-0.54/.libs/lt-crf_learn [options] files
-f, --freq=INT use features that occuer no less than INT(default 1)
-m, --maxiter=INT set INT for max iterations in LBFGS routine(default 10k)
-c, --cost=FLOAT set FLOAT for cost parameter(default 1.0)
-e, --eta=FLOAT set FLOAT for termination criterion(default 0.0001)
-C, --convert convert text model to binary model
-t, --textmodel build also text model file for debugging
-a, --algorithm=(CRF|MIRA) select training algorithm
-p, --thread=INT number of threads(default 1)
-H, --shrinking-size=INT set INT for number of iterations variable needs to be optimal before considered for shrinking. (default 20)
-v, --version show the version and exit
-h, --help show this help and exit
I 'm wondering if any one could help me?
I don't think that's a bug in CRF++, since you are able to run it from command line. So the actual question is how to pass arguments properly when starting a process using Runtime.exec(). I would suggest trying the following:
String[] cmd = {"/home/toshiba/Bureau/CRF++-0.54/.libs/lt-crf_learn",
"/home/toshiba/Bureau/CRF++-0.54/example/atb/template",
"/home/toshiba/Bureau/CRF++-0.54/example/atb/tr_java.data"};
Process p = Runtime.getRuntime().exec(cmd);
This may help since Runtime.exec() sometimes splits the command line into arguments in a rather strange fashion.
Another potential problem is mentioned here: Java Runtime.exec()
There's a simple solution for this. Just write your command into a temporary file and execute that file as Runtime.getRuntime.exec("sh <temp-filename>"). Later you can delete this file. I will explain reason behind this if this solution works for you.

As a command it runs fine from cmd prompt but not from java code

The code given below actually tries running a command. This command when run from command prompt, produces the necessary output. But when i try to run the application from java code, it keeps on running and doesn't produce any output file.
String arg[]={"C:\\app1.exe", "C:\\app2.exe", "c:\\app3.exe"};
String pwd[]={"123","-x","-sf"};
String outputfile="c:\\output.xml"
String command=arg[0]+pwd[0]+arg[1]+pwd[1]+arg[2]+pwd[2]+output;
Process pr=rt.exec(command);
String command=arg[0]+pwd[0]+arg[1]+pwd[1]+arg[2]+pwd[3]+output;
At least you are missing the whitespace between the arguments!
You should not concatenate all arguments to one string. Instead, pass them as separate arguments to
Process exec(java.lang.String[])
I think you made mistake in generating command.
It would be
C:\\app1.exe123C:\\app2.exe-xc:\\app3.exe-sfc:\\output.xml
Make sure the space
And use this exec(String[]
My guess is that you haven't tried this in a debugger or printed what it is trying to run.
My guess is that when you make this compile, you don't have a command called.
C:\app1.exe123C:\app2.exe-xc:\app3.exe-sfc:\output.xml
You cannot have more than one : in the path.
You concatenate all commands and args, but you never insert spaces between the commands and args.
So your command looks like this: "C:\app1.exe123C:\app2.exe-xc:\app3.exe-sfc:\output.xml"
And also pwd[3] doesn't exist. You have an array with 3 elements, so the highest element would be pwd[2]. You should get and ArrayIndexOutOfBoundsException here (or is it just a copy-paste-mistake)?
Well there's a couple of things wrong with the code:
A space is needed between the commands and the arguments and pwd[3] is out of bounds. I ran this code and it works.
String arg[]={"C:\\app1.exe", "C:\\app2.exe", "c:\\app3.exe"};
String pwd[]={" 123"," -x"," -sf"};
String outputfile="c:\\output.xml";
String command=arg[0]+pwd[0]+arg[1]+pwd[1]+arg[2]+pwd[2]+outputfile;
try {
Process pr=Runtime.getRuntime().exec(command);
} catch (IOException e) {
e.printStackTrace();
}
Try:
String[] command = new String[] { arg[0], pwd[0], arg[1], pwd[1],
arg[2], pwd[2], output };
This is assuming the command you wish to run is
C:\app1.exe 123 C:\app2.exe -x C:\app3.exe -sf c:\output.xml
If you really want to run three separate commands, you will have to run exec() more than once.
See the javadoc at http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Runtime.html#exec(java.lang.String[]) for details.
EDIT: As another answerer has pointed out, there is no pwd[3]!
If your apps "app1", "app2" ... are run from the command prompt you need open that before.
by launching cmd.exe first of all.
And then as others suggested add space between app and arguments.
Try by pasting this in the Run/Search input field in windows:
cmd.exe /K C:\app1.exe 123 C:\app2.exe
-x c:\app3.exe -sf c:\output.xml
cmd.exe /K keeps the propmt open after executing commands

Categories