I try to execute a shell command via java like this
if (Program.isPlatformLinux())
{
exec = "/bin/bash -c xdg-open \"" + file.getAbsolutePath() + "\"";
exec2 = "xdg-open \"" + file.getAbsolutePath() + "\"";
System.out.println(exec);
}
else
{
//other code
}
Runtime.getRuntime().exec(exec);
Runtime.getRuntime().exec(exec2);
but nothing happens at all. When I execute this code it prints /bin/bash -c xdg-open "/home/user/Desktop/file.txt" in the console, but does not open the file. I have also tried to call the bash first and then the xdg-open-command, but there is not change.
What's the problem here and how can I solve this?
EDIT: The output of the calling looks like this:
xdg-open "/home/user/Desktop/files/einf in a- und b/allg fil/ref.txt"
xdg-open: unexpected argument 'in'
But this seeems very strange to me - why is the command seperatet before the in even the entire path is set in quotation marks?
Please note that you don't need xdg-open to do this.
You can use the java platform-agnostic Desktop API:
if(Desktop.isDesktopSupported()) {
Desktop.open("/path/to/file.txt");
}
Update
If the standard approach still gives issues, you can pass the parameters as an array since Runtime.exec does not invoke a shell and therefore does not support or allow quoting or escaping:
String program;
if (Program.isPlatformLinux())
{
program = "xdg-open";
} else {
program = "something else";
}
Runtime.getRuntime().exec(new String[]{program, file.getAbsolutePath()});
Related
I have this program that I am writing that has this method that is supposed to execute a program but does not do anything. The method in question is as follows:
public void findCC_Data(List<String> l7) {
StringBuffer output = new StringBuffer();
Process p;
try {
for(String sql_file: l7) {
String command = "cleartool describe " + sql_file;
p = Runtime.getRuntime().exec(command);
System.out.println("Executing: " + command);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
if (reader.readLine() == null) {
System.out.println("'reader.readLine()' is equal to null");
}
}
} catch(Exception e) {
e.printStackTrace();
}
System.out.println(output.toString());
}
Does anyone know why the command does not do anything and the reader.readLine() method always returns null?
I am following a tutorial but using the cleartool program instead of the ping program basically. The tutorial is at this URL:https://www.mkyong.com/java/how-to-execute-shell-command-from-java/
Solution
I had the System.out.println(output.toString()) print statement outside of the for loop instead of inside it. Now when I move the SOP statement inside the loop it prints a million plus lines of information on ClearCase version control stuff. To fix put the SOP with the output.toString() inside the loop in the broken code above.
One possibility for a program in (java, python, bash, ...) to do nothing with ClearCase command is if said cleartool command is run within a dynamic view which has been set (cleartool setview).
As I explained before, the cleartool setview command opens a subshell in which commands are supposed to be run, which is not the case here (the java program runs in the main shell)
The other possible cause is that you are reading stdout, not stderr, and somehow this commands returns an error (maybe its execution path is not correct).
thought it would not matter anyway because a method I call before the one in question is supposed to change directories to the dynamic view. It appears it does not work as expected though because the result of the cleartool pwd command is just my desktop
Yes, each cleartool command operates in its own shell. You must set the right execution folder for each Java Process run("cleartool ...") commands, in order for those cleartool commands to start in the right folder.
See "execute file from defined directory with Runtime.getRuntime().exec", although the answer is a bit dated, and that might have changed with Java8.
As the OP noted, the output.toString() print statement was outside of the for loop instead of inside said loop.
You can see additional example in:
"Capturing stdout when calling Runtime.exec"
"No output from Runtime.getRuntime().exec(“ls”)"
Run your command inside a child shell using sh command and redirect the output to nohup, refer nohup and sh command.
once you have the command executed i.e. "nohup cleartool describe " + sql_file;
you can get the error or details from nohup.out file and confirm if there is an issue in executing the command.
I am trying to execute the following command from a java program:
java -jar /opt/plasma/fr.inria.plasmalab.plasmalab-1.3.4.jar -t -a montecarlo -A"Total samples"=1000 -m models/translated/plasma/NaCl2.rml:rml --format csv -r models/translated/plasma/NaCl2.bltl:bltl
with the following code:
String totalSample = "-A\"Total samples\"=1000";
String mcCommand = "java -jar " + MChecker.getAppPath() + " -t "
+ "-a " + "montecarlo " + totalSample
+ " -m " + mcModelRelPath + ":rml " + "--format " + "csv "
+ "-r " + customQueryRelPath + ":bltl";
Process process = Runtime.getRuntime().exec(mcCommand);
int errCode = process.waitFor();
//then get the output, and error
But it results in the following error:
Wrong parameter description : Dynamic parameter expected a value of the form a=b but got:"Total
I ran the same command in a terminal and it worked without any problem. But when I create the command in Java and try to invoke the tool it does not work.
I think it's confused because of the totalSample parameter which includes a space. What I did next was to put "\ " space escape in paramater(String totalSample = "-A\"Total\\ samples\"=1000";), but it still refused to accept it. It gave the following error:
Wrong parameter description : Dynamic parameter expected a value of the form a=b but got:"Total\
Then I run the same parameters with the ProcessBuilder object, like the following:
String[] mcCommand = {"java", "-jar", MChecker.getAppPath(), "-t",
"-a", "montecarlo",totalSample, "-m",
mcModelRelPath + ":rml", "--format", "csv", "-r",
customQueryRelPath + ":bltl" };
ProcessBuilder pb = new ProcessBuilder(mcCommand);
Process process = pb.start();
process.waitFor();
But it still did not work and threw some custom exceptions.
I am currently out of options -- do you have any idea why this command does not work with Java, when it works just fine from the terminal interface?
BTW: I ran the same code on Windows it worked perfectly, but I have to run this code on Ubuntu OS.
Many Thanks
It was weird that, Java Process and ProcessBuilder classes could not pass the parameters properly. I don't know why, but since I was able to execute the command from terminal. I decide to call the terminal first and then execute the command. Therefore, I changed my command as following
String mcCommand[] = {
"/bin/sh",
"-c",
"java -jar /opt/plasma/fr.inria.plasmalab.plasmalab-1.3.4.jar -t -a montecarlo "+totalSample+" -m models/translated/plasma/NaCl2.rml:rml --format csv -r models/translated/plasma/NaCl2.bltl:bltl" };
Despite it is platform dependant solution, currently it is ok for me.
Don't add extra quotes for Total samples when using ProcessBuilder:
ProcessBuilder pb = new ProcessBuilder("java", "-jar", MChecker.getAppPath(), "-t",
"-a", "montecarlo", "-ATotal samples=1000",
"-m", mcModelRelPath + ":rml", "--format", "csv",
"-r", customQueryRelPath + ":bltl");
//...
I have written a code to execute a script from java :
String wrapper_script=homedir+"/blast_distribute.sh "+" --seqs="+seqs+" --i="+formobj.getUpFile().getFileName()+" "+formobj.getSelected_program();
script_exec=Runtime.getRuntime().exec(wrapper_script);
This works perfect for me as command is executed successfully. Now I need to run this command as other user so I need to execute a command in a format like :
su username -c 'command'
SO I have edited above script_exec string as :
String wrapper_script1="su - "+username+" -c "+"'"+wrapper_script+"'";
I have printed wrapper_script1 which diplays:
su - abhijeet -c '/home/abhijeet//blast_distribute.sh --seqs=1562
--i=mPS_0.contigs.fasta'
If I run same command directly on Linux,It works exactly as I need.But When I am running through :
script_exec=Runtime.getRuntime().exec(wrapper_script1);
It does't work properly ,In my error stream I get error as
su: unrecognized option '--seqs=1562' Try `su --help' for more
information.
I have tried a lot but could't resolve the issue.What can be the reason for this issue?
You should use multiple parameters run for this:
Runtime.getRuntime().exec(new String[] {"su", "-", username, "-c",
homedir + "/blast_distribute.sh " + " --seqs=" + seqs + " --i=" + formobj.getUpFile().getFileName() + " " + formobj.getSelected_program()
});
You're getting the error, because ' is not treated here as a enclosing characters, but as a parameters for su command.
Let's look into details. When you type into console some command like su - jsmith -c 'aba --cabga', what you're doing is: "run command su with such an arguments: -, jsmith, -c, aba --caba (one argument for multiple words)".
The same thing you should do in your Java code. There's special command in Java API for running the concrete command with concrete arguments instead of parsing line as shell do: Runtime.exec(String[]): the first argument is command, the next are the arguments. That's what we do in this code block.
Am trying to pop up a CMD then execute some Commands such as:
echo SOMETHING && echo SOMETHING && mkdir....etc
i managed to open the CMD but JAVA doesnt seem to recognize "&" inside string
the first command which before the "&" is the only being executed
any tips ?
try {
// Execute command
String command = "cmd /c start echo hello baby & echo the world";
Process child = Runtime.getRuntime().exec(command);
// Get output stream to write from it
} catch (IOException e) {
}
}
}
It's &&, not &.
A double ampersand is a logical "and", a single ampersand means "put the (first!) process into the background".
PS: By "cmd", do you mean the good ol' Windows cmd.exe? If yes, I don't know if those ampersands are working there. Try the PowerShell instead if so.
I am facing a weird issue with executing a system command from JAVA code.
Actually i want to get the Mac OSX system information from my JAVA App.
For that im using
Runtime.getRuntime().exec("system_profiler -detailLevel full");
This is working fine.If i print the output,it is cool.
But i want to write this information to a plist file for future use.For that im using the -xml argument of system_profiler.like,
String cmd = "system_profiler -detailLevel full -xml > "+System.getProperty( "user.home" )+"/sysinfo.plist";
Process p = Runtime.getRuntime().exec(cmd);
Basically this should create a plist file in the current users home directory.
But this seems to be not writing anything to file.
Am i missing something here ?
My Java is more than rusty, so please be gentle. ;-)
Runtime.exec() does not automatically use the shell to execute the command you passed, so the IO redirection is not doing anything.
If you just use:
"/bin/sh -c system_profiler -detailLevel full > path/file.plist"
Then the string will be tokenized into:
{ "/bin/sh", "-c", "system_profiler", "-detailLevel", "full", ">", "path/file.plist" }
Which also wouldn't work, because -c only expects a single argument.
Try this instead:
String[] cmd = { "/bin/sh", "-c", "system_profiler -detailLevel full > path/file.plist" };
Process p = Runtime.getRuntime.exec(cmd);
Of course, you could also just read the output of your Process instance using Process.getInputStream() and write that into the file you want; thus skip the shell, IO redirection, etc. altogether.
Christian.K is absolutely correct. Here is a complete example:
public class Hello {
static public void main (String[] args) {
try {
String[] cmds = {
"/bin/sh", "-c", "ls -l *.java | tee tmp.out"};
Process p = Runtime.getRuntime().exec (cmds);
p.waitFor ();
System.out.println ("Done.");
}
catch (Exception e) {
System.out.println ("Err: " + e.getMessage());
}
}
}
If you weren't using a pipe (|) or redirect (>), then you'd be OK with String cmd = "ls -l *.java", as in your original command.
If you actually wanted to see any of the output in your Java console window, then you'd ALSO need to call Process.getInputStream().
Here's a good link:
Running system commands in Java applications