I made a new process, but it never finishes.
I was trying with ProcessBuilder and Runtime but none of it worked, both got stuck.
Builder code:
ProcessBuilder a = new ProcessBuilder(
"java",
"-classpath",
"D:\\TAP",
"AnalizadorLexico",
"<",
"D:\\TAP\\Lol1.txt");
Process process=a.start();
Runtime code:
Process process=cmd.exec(
"java -classpath D:\\TAP AnalizadorLexico < D:\\TAP\\Lol1.txt ");
The command works in Windows CMD.
From comments:
The "<" works with cmd(or other shells). Java program does not interpret it as input. You can use "cmd /c java progr < input ", but that makes it windows specific.
A better way will be to use real Java APIs for it: See ProcessBuilder
Once you get past this , please check another FAQ item on this
Related
I'm trying to use ProcessBuilder in Java to run some python code. print is causing errors but print() works fine.
The java code is:
List<String> list = Arrays.asList("python", "C:/.../test.py");
ProcessBuilder pb = new ProcessBuilder(list);
Process process = pb.start();
It generates a file if test.py is this
open('C:/.../outputtest2.txt', 'a')
print(5)
but it doesnt't work if test.py is this
open('C:/.../outputtest2.txt', 'a')
print 5
Both work fine if I run the script from the command line. I've tried changing and even removing Python 3 from the PATH but still getting the error. I can't find any similar errors online.
This is a python syntax error. As you know in python 3 you have to put parentheses for print function. for some reasons ( e.g. system cache) your ProcessBuilder use python 3 for running your python code.
This problem should solve by restarting the computer but if it doesn't work, you can run it manually with python 2.x
For example :
List<String> list = Arrays.asList("C:/python27/python.exe", "C:/.../test.py");
ProcessBuilder pb = new ProcessBuilder(list);
I know there are a lot of post about executing commands from Java but I just can't get this to work. Here is what I'm trying to do, I have a bash script, it receives 2 arguments which might or might not have spaces, then from Java I'm executing the script and passing the arguments like this(I'm surrounding the arguments with quotes and escaping them with backslashes):
String cmd = "/opt/myScript \"/opt/myPath1\" \"/opt/myPath2 with spaces\"";
Runtime rt = Runtime.getRuntime();
rt.exec(cmd);
I also tried to use the ProcessBuilder class like this:
String myScript = "/opt/myScript";
String myArg1= "/opt/myPath1";
String myArg2 = "/opt/myPath2 with spaces";
ProcessBuilder pb = new ProcessBuilder(myScript , myArg1, myArg2);
pb.start;
Arguments with no spaces are received successfully but I still have problems with the second one.
I thought the ProcessBuilder class would handle the spaces but seems like I'm missing something.
I'm not sure if it has something to do, but just in case here is my script:
#!/bin/bash
PATH=$PATH:$1
gnome-terminal --working-directory $2
$1 and $2 are the arguments sent from Java.
Get the same trouble, finally solved with:
Runtime.getRuntime().exec(new String[]{"bash", "-c", <command with spaces>});
Runtime.exec() is an overloaded method. There are several possible ways how to call it. The call exec(String command) executes the specified string command but the argument are separated by spaces here. The method exec(String[] cmdarray) executes the specified command and arguments. There are other exec() variants but the best for you is
String cmd[] = new String[] {"/opt/myScript", "/opt/myPath1", "/opt/myPath2 with spaces" };
Runtime rt = Runtime.getRuntime();
rt.exec(cmd);
It is possible to use ProcessBuilder can be used as well for argument passing. I think the only error is missing parenthesis after pb.start.
And last but not least the script has a major bug. It does not contain quutes arround $2. It should be
#!/bin/bash
PATH="$PATH:$1"
gnome-terminal --working-directory "$2"
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.)
I'm looking to call the command line from a java program. I have successfully entered the command line using this bit of code
String[] cmd = new String[2];
cmd[0] = "cmd /c dir";
Runtime rt = Runtime.getRuntime();
System.out.println("Execing " + cmd[0]);
Process proc = rt.exec(cmd[0]);
However, the actual commands aren't working. I am not too familiar with command line, I have only ever typed directly into it. So my question is how do I pass multiple arguments in? For instance if I wanted to change to C:\ I would have thought I could just add cd\ on the end but this doesn't seem to work?
Thanks in advance
use the & symbol. Everything needs to go in at once. For instance: cd .. & echo "test" will go to the previous directory and then echo test.
Taken from here: http://forums.techguy.org/dos-other/697113-solved-multiple-commands-cmd.html
Please see the code below
Runtime rt = Runtime.getRuntime();
rt.exec("cmd /c start");
String[] cmd = {"LogParser", "Select top 10 * into c:\temp\test9.csv from application" };
rt.exec(cmd);
It opens the command window but the strings are not passed in after opening. Can someone tell me why this code won't place the strings into the command window?
The option /C means: Carries out the command specified by the string and then terminates.
So the other command is handled as a separated one.
Use OutputStreamWriter and write to the input stream of the process created.
Process p = Runtime.getRuntime().exec("cmd /K start") ;
Writer w = new java.io.OutputStreamWriter(p.getOutputStream());
w.append(yourCommandHere);
Also, the reason for using /K :
/K Run Command and then return to the CMD prompt.
Reference : http://ss64.com/nt/cmd.html
Why not use this:
String[] cmd = { "cmd /c", "LogParser",
"Select top 10 * into c:\temp\test9.csv from application" };
rt.exec(cmd);
Find more info about the exec method here.
You'll first need to start a process as you do in your first two lines of code, but don't use start because that spawns a separate process and returns immediately. Use just LogParser instead, or whatever will make your LogParser process start without involving cmd. After that you need to retrieve the OutputStream of the Process object created by exec and write your select command into it. You will also need to read from the Processs InputStream to see the response. None of this will be visible in a separate command-prompt window; you'll need to process everything through Java and it will involve some multithreading as well.
As I said in my comment - 'They are executed as separate commands, they are not related just because you executed one before the other'
From the Runtime.exec( string ) javadoc -
Executes the specified command and arguments in a separate process.
You need to chain the commands together to get cmd to process your command, I believe you need to use the \k flag to specify what commands you need executed on the command line.
Runtime rt = Runtime.getRuntime();
String start = "cmd /k ";
String cmd = "LogParser;\n" Select top 10 * into c:\temp\test9.csv from application";
rt.exec(start + cmd);
Not tested as I don't have windows, but it should be similar to this.