I have a bit of a weird situation. I'm writing a Java program to communicate automatically with Transmission on my Raspberry Pi (Linux).
I have the following code (simplified and edited for convenience/security):
String s;
String fullCommand = "transmission-remote -n username:password -a /location/to/file.torrent";
String[] cmd = fullCommand.split(" ");
Process p = Runtime.getRuntime().exec(cmd);
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((s = br.readLine()) != null) {
System.out.println("line: " + s);
}
p.waitFor();
System.out.println("exit: " + p.exitValue());
p.destroy();
The output I get is "non-existing or invalid torrent file".
If I run the exact same script on the command line, I get success (so the file exists and is valid).
I've read that Runtime.exec() has problems with spaces. Hence the split(" ").
It does not work without it either.
I know Runtime.exec() isn't the same as command line, but is there any way I could get this working?
I have a workaround, but I'd like to do it in one step.
If anyone is interested: the workaround is writing the command to a .sh file, make it executable and run that using Runtime.exec(). This does work.
Related
I have been trying to start Steam from inside my Java program.
I have tried this:
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec("cmd.exe start \"\" \"C:/Program Files (x86)/Steam/Steam.exe\" -login myid mypassword"); //the string amounts to start "" "C:\Program Files (x86)\Steam\Steam.exe" -login myid mypassword
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
System.out.println(output);
This would do nothing. I don't even get any error. My mouse becomes a loading mouse as if something is loading in the background. But actually nothing happens.
Although, when I try to run commands such as taskkill /F /IM Steam.exe, they work perfectly fine and actually I see Steam closing.
I was able to run it by removing start.
Runtime.getRuntime().exec("cmd.exe \"C:/Program Files (x86)/Steam/Steam.exe\" -login myid mypassword");
Even removing cmd.exe worked as well
Runtime.getRuntime().exec("\"C:/Program Files (x86)/Steam/Steam.exe\" -login myid mypassword");
But I ran into a very little problem, which I will ask some other time. That little problem is that the process won't execute the next instruction unless I close the Steam. I tried to run it with cmd.exe /c flag, but that didn't work either.
I've been having problems reading output of windows command line from Java, i'm using Runtime.getRuntime().exec()
I simplified my test case: I have a file called お読みください.txt, and i execute the following command cmd /c dir C:/PATH
Note: The actual command is tasklist, but it's the same result as long as i use Runtime.getRuntime().exec()
String[] cmd = new String[]{ "cmd", "/c", "dir" };
Process process = Runtime.getRuntime().exec(cmd);
BufferedReader stdInput =
new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
String s, result = "";
while ((s = stdInput.readLine()) != null) {
if (!s.isEmpty()) {
result += s + "\n";
}
}
System.out.println(result);
I just get ���ǂ݂�������.txt
I tried with no charset, default, and the other ones; after testing all charsets, i got the one i was looking for: Shift_JIS
And that must be because i have set Language for non-Unicode applications as Japanese. systeminfo.exe says ja;Japanese for Regional Config.
I can simply use Shift_JIS to read, but it will only work in my computer. What about other system configurations?
The question is, how can i get the correct charset to read Windows Console output?
Base on the answer of What encoding/code page is cmd.exe using?
You can execute cmd /k chcp && pause && exit to get current code page. Using Code Page Identifiers to find the mapping Java encoding name.
I want to run a script with ssh from java. The script takes a number as parameter. I launch this code :
String myKey="/home/my_key.pem";
Runtime runtime = Runtime.getRuntime();
String commande = "ssh -i "
+myKey+" ubuntu#ec2-56-75-88-183.eu-west-1.compute.amazonaws.com './runScript.bash 8000'";
Process p = runtime.exec(commande);
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
p.waitFor();
I obtain this error :
bash: ./runScript.bash 8000: No such file or directory
The name of file is correct. chmod given to runScript.bash is 777.
When i run the command line directly from bash it works. But from IDE, it does not.
How can i do to run this commande line correctly please ?
The error makes it clear:
bash: ./runScript.bash 8000: No such file or directory
This indicates that the shell is trying to invoke a script called ./runScript.bash 8000 -- with the space and the 8000 in the filename of the script.
It's rare for me to be telling anyone to use fewer quotes, but, well, this is actually a case where that would fix things.
Better would be to avoid double evaluation altogether:
Runtime.exec(new String[] {
"ssh",
"-i", myKey,
"ubuntu#ec2-56-75-88-183.eu-west-1.compute.amazonaws.com",
"./runScript 8000"
})
I've got a java application that will eventually get fairly deep into external process integration, including IPC with those processes. For now though, what I'm trying to do is simply run a powershell script from java.
what I've got:
private void runPowershellScript() {
String command =
"" + "powershell" + " ";
// Paths.get("").toAbsolutePath() + "\\" + scriptFileName + " " +
// Paths.get("").toAbsolutePath() + "\\" + INPUT_FILE_NAME + " " +
// Paths.get("").toAbsolutePath() + "\\" + OUTPUT_FILE_NAME + "";
try {
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process process = builder.start();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine ()) != null) {
System.out.println ("Stdout: " + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
With what you see there, I get the Windows Powershell name and copyright coming out over that reader, but if I add any of the commented out lines (all of which resolve to proper paths, eg C:\Users\Geoff\Code\OPTIP\FakeProgram.ps1) I get:
java.io.IOException: Cannot run program "powershell C:\Users\Geoff\Code\OPTIP\FakeProgram.ps1 ": CreateProcess error=2, The system cannot find the file specified
I've tried a dozen different combinations of strong and weak quotes, and I've tried passing them as arguments to cmd.exe /c powershell ... but nothing I've tried runs the script. If there is a single space in the command string, I get an IO Exception.
I'm wondering if maybe it has something to do with character encoding? When I simply invoke powershell, I'm getting 'back from reader.readLine() is:
W\u0000i\u0000n\u0000 ... Which I presume is my IDE's (IntelliJ's) way of telling me its "Windows Powershell" with a null unicode character between each letter.
The Java ProcessBuilder documentation is a little vague on exactly what you can pass as arguments:
a command, a list of strings which signifies the external program file to be invoked and its arguments, if any. Which string lists represent a valid operating system command is system-dependent. For example, it is common for each conceptual argument to be an element in this list, but there are operating systems where programs are expected to tokenize command line strings themselves - on such a system a Java implementation might require commands to contain exactly two elements.
I dont know what that means. The command I'm trying to give it works from a CMD and Powershell window, and also from the windows run dialog.
gist containing the class of above method:
https://gist.github.com/Groostav/9c5913e6f4696a25430d
gist containing my powershell script:
https://gist.github.com/Groostav/347a283ac7ec6a738191
Thanks for any help.
You have to put the arguments in separate strings, not concatenating them to the powershell call as a single string.
Something like
new ProcessBuilder("Powershell", scriptFileName, INPUT_FILE_NAME);
I have run an external tool through exce() function in a separate command line console.
command = "cmd.exe /c start /min doxygen " + strDoxyfilePath;
System.out.println("command : " + command);
//pass the command to execute
Process p=Runtime.getRuntime().exec(command);
I used this for read input stream:
BufferedReader br = new BufferedReader(new InputStreamReader
(p.getInputStream(), "UTF-8")); //read output of doxygen
String line = null;
while ((line = br.readLine()) != null){
System.out.println("I M HERE: "+line);
}
But control doesn't go inside while loop and I want to get proper signal at the process end.
I think it is because of the start in your command. You are probably doing it to avoid a cmd window but I think you cannot not interact with the program then.
Try
command = "cmd.exe /c doxygen " + strDoxyfilePath;
Also, note that
You also need to read the stderr (p.getErrrorStream())
Runtime.exec is not a great way to start a child process. ProcessBuilder is the newer and better way to do it.
I think the classic When Runtime.exec() won't still explains it best.