first of all, I found a lot of questions about xterm and java, but no questions handles my problem directly.
What is my problem?
I want to start a xterm terminal from java and I want to send commands to this terminal.
First I just want to change the directory, but it does not work. But it is important, that I don't know all commands at the beginning of the program, so it is recommended, that I can send commands to the terminal at run-time.
Here is my code:
String[] command= {"xterm"};
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(command);
Thread.sleep(2000);
BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
ReadThread input = new ReadThread(in);
input.start();
BufferedReader error = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
ReadThread inputError = new ReadThread(error);
inputError.start();
PrintWriter printWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(pr.getOutputStream())),true);
printWriter.println("cd /home/***/sipp/sipp-3.3\n");
Thread.sleep(2000);
input.die();
inputError.die();
printWriter.close();
error.close();
in.close();
pr.destroy();
I thought that the terminal will open (it does) and change the directory to sipp-3.3 after 2 seconds. Another 2 seconds later the xterm should close (it does).
But what is the problem, that my command does not work?
And please I don't want to find a solution like
String [] gggg = {"xterm", "-c", "multiple commands, with |, &&, ; etc"};
rt.exec(gggg);
Because with a solution like this, I am not able to send further commands to the terminal.
Many thanks in advance!
Related
I'm trying to use Runtime.getRuntime().exec() to call a program as if it was called from the terminal, but it just crashes with a fatal error after reading the first file.
In the terminal I run the command like so:
mace4 -c -f inputFile.in > outputFile.out
It works as expected, reading from the first file and outputting in the second one.
In Java I try to run it this way:
String args[] = new String[]{"mace4", "-c", "-f", inputFileName ,">",outputFileName};
try {
String s;
Process proc = Runtime.getRuntime().exec(args, null, new File("/home/user/workDirectory/"));
BufferedReader br = new BufferedReader(
new InputStreamReader(proc.getInputStream()));
while ((s = br.readLine()) != null)
System.out.println("line: " + s);
proc.waitFor();
proc.destroy();
As soon as the program reaches the end of the first file, it throws this:
Fatal error: read_all_input, file > not found
The program is quite old and I can't seem to find a way to get a more detailed error out of it..
I tried calling it with these arguments {"sh or bash", "-c", "mace4", "-c", "-f", inputFileName ,">",outputFileName} which makes the program run and then freeze (or at least nothing appears in the console)..
Am I calling the terminal command wrong and if yes what should I change?
PS: this is my first question here, if I missed anything, I'm sorry..
It looks like you're trying to use the Bash output redirection operator >. This redirects the output of the program you're running to a file (or another program)
This answer explains how to do this using ProcessBuilder which should work for what you're trying to do here.
For example:
ProcessBuilder pb = new ProcessBuilder("mace4", "-c", "-f", inputFileName);
pb.redirectOutput(new File(outputFileName));
Process p = pb.start();
To excecute SENNA in the terminal I use the command:
senna.exe < input.txt > result.txt
Now I want to realize this in a java program. This is my code so far
ProcessBuilder builder = new ProcessBuilder("senna.exe");
builder.redirectErrorStream(true);
Process process = builder.start();
OutputStream stdin = process.getOutputStream();
InputStream stdout = process.getInputStream();
BufferedReader reader = new BufferedReader (new InputStreamReader(stdout));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
writer.write("This is a test sentence");;
writer.flush();
String line;
while ((line = reader.readLine ()) != null) {
System.out.println ("Stdout: " + line);
}
To redirect the input, output and error stream I used the code from this thread. The problem is that I get the following error message:
FATAL ERROR: unable to open file hash/words.lst
Am I doing something wrong?
From the examples you've given it seems that you're adapting Linux code from this thread to run on Windows with senna.exe.
From the error you're getting it seems that you forgot to change Linux's forward slash (/) to Windows' backslash (\).
Try changing your filepath's forwardslash to backslash.
As far as I can see, you haven't set the directory path to ProcessBuilder object. This error seems to be because there is a folder called 'hash' in senna folder which can't be reached.
Please try this:
builder.directory(new File("/yourpathtosenna/senna/")); (I am on a linux machine)
Your error should most probably change, but I am not sure if you will get the output as I am also struggling with running senna interactively through Java on a Linux machine at the moment.
Good luck and do update if you are successful!
I Asked some days ago about executing python script from java. It solved my problem partially. But now, I am not able to pass any parameter and make that script to do anything.
My script has to receive a XBee frame and send it by serial port. I tested the script in shell and it works fine. So, doing: sudo python script.py frame, the frame is sent.
Now, I tried to do the same with java, and it fails. My code is:
Process p;
//System.out.println(packet.toString());
try{
StringBuffer p1 = new StringBuffer();
String[] cmd = {"/bin/bash", "-c", "echo pass | python script.py b'", packet.toString(), "'"};
p = Runtime.getRuntime().exec(cmd);
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String s = br.readLine();
p.waitFor();
p.destroy();
} catch (Exception e) {}
I have to add b' before argument and another ' after it. packet is StringBuffer so I get the String with toString method.
I need to run it as root because it uses serial port and if not, it says to me I have not permission.
Do you know how to do it? I tried to write a file with some word when I run the script but nothing happends, which makes me think about it doesn't run properly.
I'm trying to use Java to interface with a large batch file that uses psexec to execute commands on remote servers.
I'm able to launch the file using process builder and it works fine for most commands, but seems to be getting hung up.
One particular command from the batch file is as follows:
ECHO .
Echo Which would you like to reboot?
Echo 1-10. For computers, enter computer number.
Echo E. Exit
set /p userinp=choose a number(0-22):
but from Java I get:
.
Which would you like to reboot?
1-10. For computers, enter computer number.
E. Exit
and then it hangs
It's clearly not reading the set line, but more importantly I haven't yet figured out how to pass input back to the subprocess.
String[] command = {"cmd", "/c", "batchfile", "restart"};
ProcessBuilder builder = new ProcessBuilder(command);
builder.directory(new File("C:\\"));
Process process = builder.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
Any input would be appreciated.
Your batch job requires that you actually provide input in order to proceed, which is why it appears to 'hang'. You need to supply this input to the process, via its output stream. A highly simplified example:
PrintWriter writer = new PrintWriter(process.getOutputStream());
writer.println("10");
writer.flush();
Your process doesn't hang, it is just waiting for some input at the command line, before to proceed.
As you are reading the output from the process via Process.getInputStream(), you can send input back to it using Process.getOutputStream().
public abstract OutputStream getOutputStream()
Gets the output stream of the subprocess. Output to the stream is piped into the standard input stream of the process represented by this Process object.
Implementation note: It is a good idea for the output stream to be buffered.
Returns:
the output stream connected to the normal input of the subprocess.
I'm trying a new approach to a hitch I've been stuck on. Instead of using expect4j for my SSH connection, (I couldn't figure out a way past blocking consumer runs and issues with closures, see past posts for more info on that if you're knowledgeable and feeling saintly,) I'm going to try to use an expect script. I have a runtime exec coded in to a button.onclick, see below. Why am I getting a 127 exit value? I basically just need this expect script to ssh in, run a single set of expect and send, give me the readout, and that's it...
I'm using cygwin. Not sure if that's relevant to why this isn't working...is my sh-bang line pointing to the right place? My cygwin install is a full install, all packages, in C:\cygwin.
Why am I getting a 127 exit value instead of a readout from my server, and how do I alleviate this?
try
{
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec( new String [] {"C:\\cygwin\\bin\\bash.exe", "C:\\scripts\\login.exp"});
InputStream stdin = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(stdin);
BufferedReader br = new BufferedReader(isr);
String line = null;
System.out.println("<OUTPUT>");
while ( (line = br.readLine()) != null)
System.out.println(line);
System.out.println("</OUTPUT>");
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
} catch (Throwable t)
{
t.printStackTrace();
}
#!/usr/bin/expect -f
spawn ssh userid#xxx.xxx.xxx.xxx password
match_max 100000
expect "/r/nDestination: "
send -- "xxxxxx\r"
expect eof
The problem is that you use bash to execute an expect script. You need to use expect to execute an expect script, or bash to execute an expect script by means of a shell commandline (that would be Process proc = rt.exec( new String [] {"C:\\cygwin\\bin\\bash.exe", "-c", "C:\\scripts\\login.exp"});, note the "-c" which I have inserted) which makes use of the magic shebang at the top of your script. Or better, use only the shebang: Process proc = rt.exec( new String [] {"C:\\scripts\\login.exp"});
The exit value of 127 is a special exit value, and tells you "command not found". Which makes sense as you expect script contains many words for which no system binaries or shell builtins exist.