I am developing a Java application which will execute a console command. What the command actually does is, it will make changes to a file, then will save a copy of it with a different name to a different folder (both of the file and the output folder is specified by the user). And it requires some binary program to do this, which is a local resource of my application.
So my code is something like:
...
public void actionPerformed(ActionEvent e) {
File selectedFile = jFileChooser1.getSelectedFile();
File pathAssigned = jFileChooser2.getSelectedFile();
String file = selectedFile.getAbsolutePath();
String output = pathAssigned.getAbsolutePath();
String name = selectedFile.getName();
// What's next???
}
And the usage/syntax of the command is something like:
"command -options /package/binary.bin "+file+" "+output+"\\"+name+"-changed"
So my question would now be; What will be my next code? Should I use a Runtime? If so, then how?
And about including a local resource path to a command, does my syntax is correct?
I am still a newbie here as well as in Java programming so please be kind to your answers/comments. Thanks!
PS. The command is a platform independent by the way.
I hope the code below can help you. First you have a shell script that takes parameters.
#!/bin/bash
echo "hola"
echo "First arg: $1"
echo "Second arg: $2"
You save it in e.g. /home/dac/proj/javatest2016/src/main/java/myshellScript.sh and then you can pass the parameters from your Java code.
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
try {
ProcessBuilder pb = new ProcessBuilder("/home/dac/proj/javatest2016/src/main/java/myshellScript.sh", "myArg1", "myArg2");
pb.directory(new File("/home/dac/proj/javatest2016/src/main/java"));
Process p = pb.start();
StringBuffer output = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
System.out.println("### " + output);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
Test
### hola
First arg: myArg1
Second arg: myArg2
Related
Environment: Windows 10 (Java) -> Windows 10 (PowerShell and C#)
Java: 1.8.0_252
Trying to remotely execute a C# program via PowerShell from Java. Seem to be having issues with the path. The C# program is in a subdirectory under a shared drive.
import java.io.*;
public class CallCSharp {
public static void main(String[] args) {
try {
ProcessBuilder builder = new ProcessBuilder("powershell.exe", "/c",
"\\SharedDrive\\Data\\Bin\\Program.exe \\\\10.1.1.1 -u user -p password");
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) {
break;
}
System.out.println(line);
}
} catch (Exception e){
e.printStackTrace();
}
}
}
The error returned is
The term '\SharedDrive\Data\Bin\Program.exe' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
The path is correct and the C# program can be run successfully.
Suspect I am not formatting the ProcessBuilder call correctly.
Issue while executing hadoop command from java.lang.Process.
hadoop fs -rm -R -skipTrash pathToFolder
this command directly executed on unixbox is working but when I try to execute it from Process it says '-rm -R' unknown command.
public class Test1 {
public static void main(String[] args) throws IOException {
String[] commandToDelete = new String[]{"hadoop", "fs","-rm -R", "-skipTrash", "hdfs://pathToFolder"};
Process process = Runtime.getRuntime().exec(commandToDelete);
try {
process.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(process.exitValue());
BufferedReader errorReader = new BufferedReader(
new InputStreamReader(process.getErrorStream()));
String line = null;
while ((line = errorReader.readLine()) != null) {
System.out.println(line);
}
errorReader.close();
}
}
From same location I am able to delete file but not folder any suggestions please.
From exec(String[] cmdarray)
Executes the specified command and arguments in a separate process.
This is a convenience method. An invocation of the form exec(cmdarray) behaves in exactly the same way as the invocation exec(cmdarray, null, null).
So you below command is run in separate process thats why -rm -R is unknown command:
String[] commandToDelete = new String[]{"hadoop", "fs","-rm -R", "-skipTrash", "hdfs://pathToFolder"};
Run like below:
String command = "hadoop fs -rm -R -skipTrash hdfs://pathToFolder"
Process process = Runtime.getRuntime().exec(command);
A more robust solution (that prevents your subsequent problem with space in the path) is to stay with the String[] form but split the arguments correctly:
String[] commandToDelete = new String[]{"hadoop", "fs", "-rm", "-R", "-skipTrash", "hdfs://pathToFolder"};
I tried to use java to run some bash script and store the terminal output in a string. However, there are a lot of commands don't work in this way. It keeps showing command not found, but I can run those commands correctly in terminal, ex node --version, go --version. I guess is the path issue, but have no idea how to fix it.
Another question, when I run "python --version", it shows "Python 2.7.10" but it is in getErrorStream. Can anyone give me some hint?
public static void runscript() throws IOException {
Runtime rt = Runtime.getRuntime();
String[] commands = { "/bin/bash", "-c", "node --version" };
Process proc = null;
try {
proc = rt.exec(commands);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
}
Reply #VishalKamat comment.
when I tried using the output of "which node" as my path, which is "/usr/local/bin/node". It works!!!
But, does that mean I have to change the path when I need to get different application version info?
I thought I can easily get the info just like I do in terminal.
I try to print $PATH by java in this way
String[] commands = { "/bin/bash","-c", "$PATH" };
The error msg is :
/bin/bash: /usr/bin:/bin:/usr/sbin:/sbin: No such file or directory
I am writing a java program that takes command and run it in unix shell. I have managed to get the output, but I need the program to detect if the given command is invalid, now, if I put in an invalid command, it gives me an error. Otherwise, it's working fine. Can anybody help me with this?? Here is my code:
public class TestCommand {
public static void main(String[] args) {
TestCommand obj = new TestCommand();
String sentence ="";
Scanner scn = new Scanner(System.in);
while (sentence != " ")
{
if (sentence !="exit")
{
System.out.println("> ");
sentence = scn.nextLine();
String outPut = obj.executeCommand(sentence);
System.out.println(outPut + "\n");
}
else
{
System.exit(2);
}
}
}
private String executeCommand(String sentence)
{
StringBuffer output = new StringBuffer();
Process p;
try
{
p = Runtime.getRuntime().exec(sentence);
p.waitFor();
BufferedReader bfrd = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = bfrd.readLine())!= null)
{
output.append(line);
}
bfrd.close();
}
catch (Exception e) {
e.printStackTrace();
}
return output.toString();
}
}
Unix shell language is extraordinarily complex. Re-implementing enough of it in java to test for correctness would be a large undertaking. If you just want to find out if some shell code is syntactically correct, you can use bash with the -n option:
bash -n file_with_code_to_test
Or:
bash -n -c string_with_code_to_test
The key thing here is the -n option. It tells bash to read the commands and check their syntax without executing them. Thus, this is safe to run.
You can run these command from java just as you would other bash commands.
bash will return an exit code of 0 if the code is syntactically correct. If it isn't, it will print error messages and return an exit code of 1.
Just to be clear, this checks syntax. It will, for example, not test for the existence of needed files or commands, only that the code is would run if they did exist.
I am searching files based on extension. Now for each file found, want to run a command:
Lets assume file found: C:\Home\1\1.txt. My exe exists in: C:\Home\Hello.exe
I would like to run command something like: "C:\Home\Hello.exe C:\Home\1\1.txt"
similarly for C:\Home\ABC\2.txt - "C:\Home\Hello.exe C:\Home\ABC\2.txt"
Kindly help me how to pass a searched file as an input to execute a command.
Thanks,
Kino
You can use below program as a base and then customize further as per your rqeuirement
public class ProcessBuildDemo {
public static void main(String [] args) throws IOException {
String[] command = {"CMD", "/C", "dir"}; //In place of "dir" you can append the list of file paths that you have
ProcessBuilder probuilder = new ProcessBuilder( command );
//You can set up your work directory
probuilder.directory(new File("c:\\xyzwsdemo")); //This is the folder from where the command will be executed.
Process process = probuilder.start();
//Read out dir output
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
System.out.printf("Output of running %s is:\n",
Arrays.toString(command));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
//Wait to get exit value
try {
int exitValue = process.waitFor();
System.out.println("\n\nExit Value is " + exitValue);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Lets get you started:
Filter files using: FilenameFilter:
http://docs.oracle.com/javase/7/docs/api/java/io/FilenameFilter.html
Sample:
http://www.java-samples.com/showtutorial.php?tutorialid=384
And after you have got the files:
Use ProcessBuilder to execute:
http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html
Sample:
http://www.xyzws.com/Javafaq/how-to-run-external-programs-by-using-java-processbuilder-class/189
If you are running your app from the command line (e.g. windows cmd), and your program name is Hello.java, only thing you have to do is to put in the argument, just like you did in your example. So it looks something like:
java Hello C:\Home\1\1.txt
I did not use exe, since this is an example, and the question is tagged with "java" tag.
Your Hello.java MUST have a main method that looks like this:
public static void main(String ... args) {
}
The parameter args are the actual parameters you enter in the command line. So to get the file name, you would have to do this:
public static void main(String ... args) {
String fileName= args[0];
}
And that's it. Later on, you can do with that whatever you want, i.e. open and edit a file:
File file= new File(fileName);
//do whatever with that file.
This code will help you
public static void main(String args[]) {
String filename;
try {
Runtime rt = Runtime.getRuntime();
filename = "";//read the file na,e
Process pr = rt.exec("C:\\Home\\Hello.exe " + filename );
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line=null;
while((line=input.readLine()) != null) {
System.out.println(line);
}
int exitVal = pr.waitFor();
System.out.println("Error "+exitVal);
} catch(Exception e) {
System.out.println(e.toString());
e.printStackTrace();
}
}