I am calling a shell script from java code using :
ProcessBuilder pb2=new ProcessBuilder("/home/abhijeet/sample1.sh ");
Process script_exec = pb2.start();
Which runs successfully,But i need to pass some parameters to it , so I need to execute this script as :
param1=abc param2=xyz /home/abhijeet/sample1.sh
I have tried this code:
ProcessBuilder pb2=new ProcessBuilder("/home/abhijeet/sample1.sh ","param1=abc","param2="xyz");
But it did't work for me.How can i pass arguements to shell script while using Processbuilder for calling it?
Note:My question is about passing arguments to shellscript ,not to commands.i have read that suggested possible duplicate question , but that does't solve my problem,I tried it that way, that is for passing arguements to commands, not for shellscript
You say you need to run the command:
param1=abc param2=xyz /home/abhijeet/sample1.sh
In this case, the "param1" and "param2" strings aren't command-line arguments. This is shell syntax to set the two environment variables param1 and param2 and then invoke sample1.sh.
To accomplish this with ProcessBuilder, you need to access the builder's environment variables:
ProcessBuilder pb2=new ProcessBuilder("/home/abhijeet/sample1.sh");
pb2.environment().put("param1", "abc");
pb2.environment().put("param2", "xyz");
Process script_exec = pb2.start();
As an alternative, the command that you're trying to run uses shell syntax, so you could pass it to a shell to execute it:
ProcessBuilder pb2=new ProcessBuilder(
"/bin/sh",
"-c",
"param1=abc param2=xyz /home/abhijeet/sample1.sh");
Process script_exec = pb2.start();
Related
I was developing my spring boot server on Windows. Now I have upgraded to Ubuntu 20.04.
the project executes a python script which should return a result as a txt file with this command:
python3 -c "from main import *;main(function,'/tmp/execution12480676806364930620/executionResponse.txt')"
Thanks to this code:
List<String> items = Arrays.asList(project.getExecutorType().buildAndGetExecutionCommandByProject(project));
ProcessBuilder pb = new ProcessBuilder(items);
pb.directory(new File(project.getPath()));
Process p = pb.start();
p.waitFor(5, TimeUnit.SECONDS);
when I print in the console the array passed in the Item variable:
[python3, -c, "from main import *;main(function, '/tmp/execution12480676806364930620/executionResponse.txt')"]
and the path of the array passed in pb.directory :
/tmp/execution12480676806364930620
My problem is that the project is not running and returning nothing.
when i go to the folder and run the same command from terminal everything works.
And that on windows 10 this same process worked fine.
Looking at similar issues I modified my code like this but it doesn't change anything:
List<String> items = Arrays.asList(project.getExecutorType().buildAndGetExecutionCommandByProject(project));
ProcessBuilder pb = new ProcessBuilder();
pb.command(items);
pb.redirectErrorStream(true);
pb.directory(new File(project.getPath()));
Process p = pb.start();
p.waitFor(5, TimeUnit.SECONDS);
What am I doing wrong?
Edit :
My command for read outputs :
private String inputStreamToString(InputStream inputStream){
return new BufferedReader(
new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
.collect(Collectors.joining("\n"));
}
And I call it like that :
System.out.println(this.inputStreamToString(p.getErrorStream()));
System.out.println(this.inputStreamToString(p.getInputStream()));
What works, when I just run "python main.py" I get the errors and print them out.
I can easily add the command at the end of the main file but I don't understand why the python -c "..." is not working? I am not receiving any errors ... I manage several languages and this could be a problem for me later
Aha! On closer inspection I think you're right it's not executing anything (and thus not producing any output either normal or error for you to see).
You don't show how the array of strings is created, but your printout suggests you have actually put quotemarks in the third string. That's wrong. When you give the shell command line python -c "import this; dothat" the shell uses the quotemarks to control parsing of this command line, but it does not pass them to the python process; the args passed to the python process (shown vertically for clarity, and omitting the argv[0]=program used in C but omitted in Java) are actually
-c
import this; dothat
If you pass an argument actually containing quotemarks like
-c
"import this; dothat"
then python doesn't execute the commands import and dothat; instead it evaluates the string literal "import this; dothat" and (since it isn't running interactively) discards the result.
Try not including, or removing, the " at the beginning and end. But leave the ' inside the string value because you do want python to receive those.
Would like to execute selenium script/batch scripts using java. Based on input parameters to call script/batch scripts.
To understand, how to run script/batch using java code.
Please help me out here.
to run a bash script contained in a file in a java project, use the ProcessBuilder class like this:
ProcessBuilder procBuildScript = new ProcessBuilder ([your_script_path],arg1,arg2,...);
procBuildScript.start();
So you can pass arguments after your script path
as "script.sh",arg1,arg2
For example :
public void runMyScript(String aFirstArg, String aSecondArg){
ProcessBuilder procBuildScript = new ProcessBuilder("./your-script.sh",aFirstArg,aSecondArg);
procBuildScript.start();
}
In your script you can call these arguments using the expressions $ 1, $ 2 ... $ {10}, $ {11} corresponding to the index where the desired parameter is located :
#!/bin/bash
# your-script.sh
echo "First argument is : $1"
echo "Third argument is : $3"
I am able to invoke a java class using below command line:
java -jar <my jar name>.jar -option1 <option> "<a string value>"
However, I want to invoke it from a another Java program.
The name of the main class is XYZ
I have imported the jar as a dependency in my project.
That heavily depends on whether you want to launch it as a separate process or simply execute within the same one.
To kick it off in the same process, you could just call the main method:
String[] arguments = new String[]{"-option1", "<option>", "<a string value>"};
MyOtherMainClass.main(arguments);
To start it as a different process:
ProcessBuilder pb = new ProcessBuilder("java", "-jar", "<my jar name>.jar", "-option1", "<option>", "<a string value>");
Process process = pb.start();
int errCode = process.waitFor();
The second example was inspired by http://examples.javacodegeeks.com/core-java/lang/processbuilder/java-lang-processbuilder-example/
I am writing a servlet to run terminal commands, I have to run three commands one after the another on the same terminal.
When I use exec as shown below I am able to get the result for the single command,
Runtime rt = Runtime.getRuntime();
process proc = rt.exec("zsh");
but when I attempt to run,
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("zsh", "source ./myenv/bin/activate", "python runner.py");
it shows a warning (doesn't execute) as follows,
The method exec(String, String[], File) in the type Runtime is not applicable for the arguments (String, String, String).
I've also tried running three differed exec commands but they do not happen in the same sequence and on the same terminal, what should I do to make the above three commands to run on the same terminal sequentially and give me the output after the third command?
The three commands I intent to run are,
1. zsh
2. source ./myenv/bin/activate
3. python runner.py
all the three must be executed one after the other in the same sequence.
exec takes a String[] not a varargs list so you need to run:
Process proc = rt.exec(new String[] {"zsh", "source ./myenv/bin/activate",
"python runner.py"}, null, new File("parentdirectoryofmyenv"));
As shown you also need to include the working directory for the process or it won't be able to find "./myenv".
EDIT:
Simplifying this further. I am assuming that "source ./myenv/bin/activate" is setting the environment for the process. This can be done as follows:
Process proc = rt.exec(
new String[] {"python", "runner.py"},
new String[] {"ENV1=VAL1", "ENV2=VAL2"},
new File("parentdirectoryofrunnerpy"));
I have written a java program named Automate.java, in which the another java program named newsmail will be executed.
The problem i face here is, Automate.java is in Desktop location(should be in desktop only always due to some requirements) and newsmail is in /home/Admin/GATE521/LN_RB this location.
What must be done before the below code, such that the command prompt automatically goes to the required folder and executes the program.
String command = "java newsmail";
Process child = Runtime.getRuntime().exec(command);
You can use this exec() :
Process child = Runtime.getRuntime().exec(command, null, new File("/home/Admin/GATE521/LN_RB"));
Resources :
javadoc - Runtime.exec()
Use the new ProcessBuilder class, instead of Runtime.exec().
ProcessBuilder pb = new ProcessBuilder("java", "newsmail");
pb.directory("/home/Admin/GATE521/LN_RB");
pb.start();
You can even look at pb.environment() to change environment variables if necessary.