sending command to terminal from java with space in it - java

I am working on a java program, where i need to invoke a bash script that takes a string as an argument. so I've written the code:
Process p = Runtime.getRuntime().exec("./script \"message send\"");
but it seems as if the terminal isn't recognizing the quotes (") as quotes, and referring to the term "message send" as two arguments: "message and send", and so the script is not invoked properly.
anyone have any idea what i can do?

You can perform this by using ProcessBuilder.
ProcessBuilder processBuilder = new ProcessBuilder();
p.command("cmd_to_run", "args_if_any");
p.start();

Related

Pipe ("|") doesn't work with ProcessBuilder in Android [duplicate]

I'm trying to use Java's ProcessBuilder class to execute a command that has a pipe in it. For example:
ls -l | grep foo
However, I get an error:
ls: |: no such file or directory
Followed by:
ls: grep: no such file or directory
Even though that command works perfectly from the command line, I can not get ProcessBuilder to execute a command that redirects its output to another.
Is there any way to accomplish this?
This should work:
ProcessBuilder b = new ProcessBuilder("/bin/sh", "-c", "ls -l| grep foo");
To execute a pipeline, you have to invoke a shell, and then run your commands inside that shell.
The simplest way is to invoke the shell with the command line as the parameter. After all, it's the shell which is interpreting "|" to mean "pipe the data between two processes".
Alternatively, you could launch each process separately, and read from the standard output of "ls -l", writing the data to the standard input of "grep" in your example.
Since Java 9, there’s genuine support for piplines in ProcessBuilder.
So you can use
List<String> result;
List<Process> processes = ProcessBuilder.startPipeline(List.of(
new ProcessBuilder("ls", "-l")
.inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE),
new ProcessBuilder("grep", "foo")
.redirectError(ProcessBuilder.Redirect.INHERIT)
));
try(Scanner s = new Scanner(processes.get(processes.size() - 1).getInputStream())) {
result = s.useDelimiter("\\R").tokens().toList();
}
to get the matching lines in a list.
Or, for Windows
List<String> result;
List<Process> processes = ProcessBuilder.startPipeline(List.of(
new ProcessBuilder("cmd", "/c", "dir")
.inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE),
new ProcessBuilder("find", "\"foo\"")
.redirectError(ProcessBuilder.Redirect.INHERIT)
));
try(Scanner s = new Scanner(processes.get(processes.size() - 1).getInputStream())) {
result = s.useDelimiter("\\R").tokens().toList();
}
These examples redirect stdin of the first process and all error streams to inherit, to use the same as the Java process.
You can also call .redirectOutput(ProcessBuilder.Redirect.INHERIT) on the ProcessBuilder of the last process, to print the results directly to the console (or wherever stdout has been redirected to).

How to run python from java correctly?

I have next method:
public void callPython() throws IOException {
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("python -c \"from test import read_and_show; read_and_show()\" src/main/python");
BufferedReader bfr = new BufferedReader(new InputStreamReader(pr.getInputStream()));
BufferedReader bfre = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
String outputStr = "";
while ((outputStr = bfr.readLine()) != null) {
System.out.println(outputStr);
}
while ((outputStr = bfre.readLine()) != null) {
System.out.println(outputStr);
}
}
in python file next code:
import os
from stat import *
def read_and_show():
print('worked!')
when i call this in terminal all worked correctly (before i cd to this directory):
MacBook-Pro-Nikita-2:python NG$ python -c "from test import read_and_show; read_and_show()"
worked!
when i run this code in my java code he return error:
File "<string>", line 1
"from
^
SyntaxError: EOL while scanning string literal
What i make wrong?
P.S.: i need run python method/class/file for read, parse and show graphical data. but for this need when java run python single method (def)
When executing other programs from java, I've found it's easier to keep it as simple as possible in java and instead execute a batch file
Runtime.getRuntime().exec("chrome.exe www.google.com");
Would instead become
Runtime.getRuntime().exec("openChrome.bat");
and openChrome.bat:
chrome.exe www.google.com
This makes it easier to test the command without recompiling, but may get complicated if you need to pass variables as arguments
To use shell built-ins like echo and cd, the batch file works wonders (ie echo test | program)
The major downside is you will have a floating .bat file next to your code
If packaging to a .jar, you may need to first copy the .bat file out of the .jar before executing
You're missing the shebang statement that states where the python interpreter is. It should be line #1
#!/usr/bin/python
Runtime.exec is obsolete. It was replaced by the ProcessBuilder class a long time ago:
ProcessBuilder builder = new ProcessBuilder(
"python", "-c", "from test import read_and_show; read_and_show()", "src/main/python");
builder.redirectInput(ProcessBuilder.Redirect.INHERIT);
Process pr = builder.start();
Notice that from test import read_and_show; read_and_show() does not have double-quote characters around it. Those quotes are something used by a shell (like bash). The python command never actually sees them, and shouldn’t see them. Executing a child process from Java (or any other language, really) does not invoke a shell; it executes the command directly. Which means the quotes wouldn’t be interpreted by any shell, and they’d be passed to the python program as part of the argument.

run python script inside Java

I need to run a shell command in Windows:
c:\Python27\python.exe c:\probabilistic_cracker\process.py dic2.txt
which is running fine in a command shell.
In Java I do this:
ProcessBuilder pb = new ProcessBuilder(Arrays.asList("c:\\Python27\\python", " c:\\probabilistic_cracker\\process.py"," dic2.txt"));
Process p = pb.start();
or this
ProcessBuilder pb = new ProcessBuilder("c:\\Python27\\python", " c:\\probabilistic_cracker\\process.py"," dic2.txt");
in both cases the result is
c:\Python27\python: can't open file ' c:\probabilistic_cracker\process.py': [Errno 22] Invalid argument
Your command is built correctly but the way you pass it to ProcessBuilder isn't, as stated in its documentation you pass the args directly the way they are, there's no need to add spaces since the ProcessBuilder will take care of that for you.
ProcessBuilder pb = new ProcessBuilder("c:\\Python27\\python", "c:\\probabilistic_cracker\\process.py","dic2.txt");
So just removing those whitespaces you have in the beginning of each argument string will do the trick.

File copy using getRuntime().exec()

I am trying to copy a file. Here is the source. Note, des is string variable containing the URL.
Process process = Runtime.getRuntime().
exec("cmd.exe\t/c\tcopy\t"+source+"\t"+des);
Can anyone tell me why it does not work?
I think you should use FileUtils.copyFile() but anyways try this.
String[] command = new String[5];
command[0] = "cmd";
command[1] = "/c";
command[2] = "copy";
command[3] = "test.java";
command[4] = "D:";
Process p = Runtime.getRuntime().exec (command);
Instead of passing your command as a single string construct an array and than pass it to exec.
I tried this
String command = "cmd /c copy test.java D:";
worked fine for me.
Advice:
Use ProcessBuilder to construct the Process.
That automatically takes care of '2' - break the command into parts.
Merge the output streams (not entirely necessary, but makes it simpler to ..).
Consume (and display) the output streams.
But in general, read and implement all the recommendations of When Runtime.exec() won't.
Runtime.exec, I believe, send the string to the command processor cmd.exe. So this is running cmd.exe, running another cmd.exe inside it, and passing your arguments. I don't have a Windows machine to test it on (thank Gods) but I think there are arguments to cmd.exe to tell it to run the arguments as a command line.
Why not just use FileUtils.copyFile()?

Java execute a command with a space in the pathname

How can I execute a Java System (shell) command that has a space in the pathname?
I've tried putting quotes and a backslash (), But it does not work.
ln -s "dir1/dir2" "my\ dir/dir2"
By far the most reliable way is to use Runtime.exec(String[] cmdarray).
If you use Runtime.exec(String command), Java only splits the command on whitespace.
the command string is broken into tokens using a StringTokenizer created by the call new StringTokenizer(command) with no further modification of the character categories. The tokens produced by the tokenizer are then placed in the new string array cmdarray, in the same order.
See also g++: File not found
Or use ProcessBuilder something like this:
ProcessBuilder pb = new ProcessBuilder("ln", "-s", "dir1/dir2", "my dir/dir2");
Process p = pb.start();
Do you really need to execute it in a shell (e.g. do you need to shell expansion of things like ~ or *, etc)? If not, you could invoke ln directly:
Process p =
Runtime.getRuntime()
.exec(new String[]{"/bin/ln","-s","dir1/dir2", "my\\ dir/dir2"});
If you really need a shell, try this (this may need a little tweaking depending on how the shell processes the quotes):
Process p =
Runtime.getRuntime()
.exec(new String[]{"/bin/sh", "-c", "ln -s \"dir1/dir2\" \"my\\ dir/dir2\""});
Edit:
I was under the impression the second path has a literal backslash in it. If it's not supposed to remove the \\ from the string literals above.
None of these work on Lion. However, the following does work, and is backwards compatible for Tiger.
Runtime.getRuntime().exec(new String[]{"/bin/bash","-c","/path/to/file/space*init"});
You can use it in the following way without having to introduce any backslashes:
Runtime.getRuntime().exec(new String[]{"ln", "-s", "dir1/dir2", "my dir/dir2"});

Categories

Resources