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.
Related
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.
I am currently working on voice recognition project and I want to access certain keys based on user's voice commmand. For example If a user speaks 'a', I want to print a. I found a cmd command that does this work. This command works fine in command prompt and returns a as output. But i want to use this in my java application. I found a method that can fetch command output and prints it. But in this case it is not able to print 'a'. Please help..Here is the code snippet.
public void Voice() throws IOException {
Process p;
String work = "cmd /c nircmd.exe sendkey a press"; // used nircmd utility
p = Runtime.getRuntime().exec(work);
String output="";
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((output = reader.readLine()) !=null) {
System.out.println(output);
}
reader.close();
}
When you run Windows' command cmd from Java, keep in mind that your working directory is your project directory or the directory from where you run java. So from the symptoms you have described, it seems that when you run the nircmd utility from java, it is not found. Try giving a full path to the exe.
Replace
String work = "cmd /c nircmd.exe sendkey a press";
with
String work = "cmd /c "c:\\your-path\\nircmd.exe sendkey a press";
So for work I would like to automate something for minitab. We get results from our microscope and these need to be put into Minitab. Now I wanted to make a program that does some changes to the text file and then automatically opens minitab with a macro. I have everything working except for the auto opening of the macro with minitab.
I can launch it from cmd manually no problem, so it should be working.
Code can be found below, after compiling and running I get this error
'C:/Program' is not recognized as an internal or external command,
operable program or batch file.
Process finished with exit code 0
Which makes me believe cmd does something like:
cmd.exe,/c,c:/Program,Files/..
instead of
cmd.exe,/c,c:/program files/...
String PathExe = "\"C:/Program Files/Minitab/Minitab 17/Minitab 17/Mtb.exe\"";
String Macro = "\"c:/minitAPP/Import.mtb\"";
ProcessBuilder builder;
builder = new ProcessBuilder("cmd.exe", "/c", PathExe + " " + Macro);
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) { break; }
System.out.println(line);
There is no need to use cmd.exe to execute another .exe file. Just execute it directly, without the quotes:
ProcessBuilder builder = new ProcessBuilder(
"C:\\Program Files\\Minitab\\Minitab 17\\Minitab 17\\Mtb.exe",
"c:\\minitAPP\\Import.mtb");
By specifying an entire path as a single argument to ProcessBuilder, you ensure that the operating system will treat it as a single argument, which is the purpose of using quotations marks on a normal command line.
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 am trying to execute a program from the Java code. Here is my code:
public static void main(String argv[]) {
try {
String line;
Process p = Runtime.getRuntime().exec(new String[]{
"/bin/bash", "-c", "executable -o filename.txt"});
BufferedReader input = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
input.close();
} catch (Exception err) {
err.printStackTrace();
}
}
My OS is Mac OS X 10.6.
Now, the executable I am trying to run is supposed to spit the output to filename.txt. If I take this command and run it on the terminal, it works fine and the filename.txt gets populated also. But, from my java program the file is not created.
if instead I use executable > filename.txt then the filename.txt is created but is empty. Not sure what's wrong here. The executable I am trying to run is Xtide (if that helps).
I would really appreciate any help I can get.
Thanks,
You cannot redirect output to file and read the output in java. It's one or the other. What you want is this:
Process p = Runtime.getRuntime().exec(new String[]{
"/bin/bash", "-c", "executable -o filename.txt"});
p.waitFor();
BufferedReader input = new BufferedReader(
new InputStreamReader(new FileInputStream("filename.txt")));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
The main changes are:
p.waitFor(), since process execution is asynchronous, so you have to wait for it to complete.
The data is read from the file rather than from the output of the process (since this will be empty.)
The answer from mdma works (and I voted it up), but you might also want to consider the version where you do read the output stream directly from executable:
Process p = Runtime.getRuntime().exec(new String[]{
"/bin/bash", "-c", "executable"});
p.waitFor();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())_;
while ((line = input.readLine()) != null) {
System.out.println(line);
}
Correct me if I am wrong, but the symptoms are as follows:
exec("/usr/bash", "-c", "executable > filename.txt") creates an empty file.
exec("/usr/bash", "-c", "executable -o filename.txt") does not create a file.
One or both of the above gives an exit code of 255 when you look at it.
When you run the command from the command line as executable -o filename.txt or executable > filename.txt it works as expected.
In the light of the above, I think that the most likely cause is that /bin/bash is not finding the executable when you launch it from Java. The fact that the first example does create an empty file means that /bin/bash is doing something. But if you try to run
$ unknown-command > somefile.txt
from a bash shell prompt you will get an error message saying that the command cannot be found and an empty "something.txt" file. (You would not see the error message in your Java app because it is being written to stderr, and you are not capturing it.) The reason that the empty "something.txt" file is created is that it is opened by the shell before it attempts to fork and exec the "executable".
If this is the problem, then the simple solution is to use the absolute pathname for the executable.
Also, if you are not doing any command line redirection or other shell magic, there is no need to run the executable in a new bash instance. Rather, just do this:
Process p = Runtime.getRuntime().exec("executable", "-o", filename.txt");
then wait for the process to complete and check the exit code before trying to read the file contents.