send character to stdin of background Java process - java

I am looking to send a character to a Java process running in the background. I found this article https://serverfault.com/questions/178457/can-i-send-some-text-to-the-stdin-of-an-active-process-running-in-a-screen-sessi?answertab=active#comment155464_178470 which I thought would solve the problem, but it actually doesn't.
For testing purposes I added a line
System.out.println("This is what I read "+(int)temp);
where temp is read this way
int temp = inputStreamReader.read();
Something really weird actually happens:
I start the process in a terminal window (not in background this time)
I open another terminal and look up the process' PID
I run the command
echo q > /proc/*pid_of_the_process/fd/0
In the other window this line appears
q
so for some reason I get to see this character in the terminal where the process is running, but it is actually not read by the process, because if that was the case then I would see this line
This is what I read 113
which is what I actually get if I type 'q' from within the terminal window.
Anybody knows why do I get this funny behavior?

Related

Reading from keyboard and ignoring printed text

I am writing a java program (In Intellij) that accepts a command from the user and reacts to the command. The reaction is asynchronous (using a separate thread).
Scanner in = new Scanner(System.in);
String command = null;
do {
System.out.println("Enter command or q to exit: ");
command = in.nextLine();
System.out.println("Received "+command);
obj.react(command);
}while (!command.equals("q"));
The reacting object may take a while to react and prints a message after it finishes.
The problem is that if I start typing a command, and before I finish, the object prints something, the typed command is lost.
For example Here is a problematic scenario (The text in italics is the user input):
Enter command or q to exit:
go
Received go
goAgainobj finished reacting!
Received
In this case, when I Hit enter after the printed message, the received command is empty.
Is there any way to keep the typed characters even after something was printed?
If you use an actual console, printed output will not affect written input. If you type 'go' and the system prints 'Again', then the in-buffer still knows 'go'. This is unintuitive and bad to read, but it's practical to interrupt running scripts, or other programs.
This may already work on your IDE or your system, depending on OS ans IDE.
If you want something more 'pretty' then you need to fully control input and output, much like the 'top' command in linux (if you happen to know that).
You can handle this way of input better with the Console class. See: https://www.codejava.net/java-se/file-io/3-ways-for-reading-input-from-the-user-in-the-console #3
The most intuitive idea to solve your problem seems to read, and then remove all input at the time you want to print something, and reprint it, so you'd get:
> go
received go
obj finished reacting!
> go
...
You'd basically always print an input line yourself, after first reading and removing the already printed input. This is why you need the Console class, because there, input and output are synchronized, so if you print something, you know that no input will happen in the meantime.

Java Command Prompt Emulator

I'm trying to make a java program that commands through cmd.exe and prints their output. To do this, I'm using this code:
cmdLine = Runtime.getRuntime().exec("cmd.exe");
cmdLineOut = new BufferedReader(new InputStreamReader(cmdLine.getInputStream()));
cmdLineIn = new PrintWriter(cmdLine.getOutputStream());
// ...
cmdLineIn.println(command);
cmdLineIn.flush();
String s = null;
while ((s = cmdLineOut.readLine()) != null)
System.out.println(s);
Although, when input is given, the output is never printed.
EDIT: Solved
The cmdLineOut.readLine() doesn't return null when the input is empty, it freezes. Since readLine freezes at the end no other code is executed, I just put the printing of the readLine in a seperate thread.
If somebody wants to answer this better, go ahead.
You never actually execute the user's command, at least in the snippet you posted. Also, nearly all command prompt "commands" are actually just programs that are on the default program search path. You should probably just Runtime.getRuntime().exec(user_command) for each command. This means that you will have to set up the input and output streams like you have already done for each command. You are right to get input in a separate thread, since attempting to read input will block the current thread until there is actually input to read.
However, some commands, even under UNIX or Linux systems, are "built-in" (like cd), meaning that the command prompt (aka "shell") handles the commands internally. Your program will have to test the user input to see if they are calling a built-in, and specially handle calls to built-in commands. Your program should actually be portable to non-Windows computers. Of course, the user would use different commands (cp instead ofcopy), but the only part you would have to add would be handling for other OS' shells' lists of built-ins (or simply have your program implement a "cross-platform" set of built-ins - this is your shell program, you get to make the rules).

commande console form java

i'm trying to execute 2 commands via java programme with process
Process p = Runtime.getRuntime().exec(command1);
Process p2 = Runtime.getRuntime().exec(command2);
the problem is that the first one is ok but the seconde on cant be established
it is always bloqed in waitfor()
You might be running into the dreaded "need to empty the streams" problem. See When Runtime.exec() won't for details on it.
Also in the same article is some info on other traps you can run into if you're treating getRuntime().exec() like the command line.
When running an external procss that prints anything to stdout/stderr, you should read what it writes - otherwise it will block once it's buffer fills up.
you basically needs a thread to read from stdout and a thread to read from stderr of each process.

UNIX STDOUT end symbol

I want to execute multiple commands from Java Process but I don't want to spawn a new process for executing every command. So I made an Object called Shell that holds InputStream and OutputStream for Process.
The problem is that if I don't terminate a process by appending
"exit\n"
I can't tell where is the end of the InputStream and the InputStream gets into waiting state when I've read the whole output so I need to know when to stop doing next read.
Is there some kind of a standard symbol at the end of the output?
Because what I came up with is
final String outputTerminationSignal = checksum(command);
command += ";echo \"" + outputTerminationSignal + "\";echo $?\n"
This way when I get the outputTerminationSignal line I can get the exit code and stop reading.
final String line = bufferedReader.readLine();
if (line != null && line.equals(outputTerminationSignal)) {
final String exitCode = bufferedReader.readLine();
}
Of course this is exploitable and error-prone because the real output in some case may match my generated outputTerminationSignal and the app will stop reading when it shouldn't.
I wonder if there is some standard so called "outputTerminationSignal" comming from the output I am not aware of.
Unix doesn't use a special character or symbol to indicate the end of a stream. In java, if you try to read from a stream that's at end-of-file, then you'll get an EOFException.
Having said that, if you're reading from a stream connected to a running program, then you won't get an EOFException just because the other program is idle. You would only get an EOFException if the other program has exited, or if it explicitly closes its output stream (that you are reading from). The situation you describe sounds like the shell is just idle waiting for another command. You won't get an EOF indication from the stream in this case.
You could try getting the shell to print a command prompt when it's waiting for a command, then look for the command prompt as an "end of command" indicator. Shells normally print command prompts only when they're interactive, but you might be able to find a way around that.
If you want to make the shell process exit without sending it the "exit" command, you could try closing the stream that you're using to write to the shell process. The shell should see that as an end-of-file and exit.
You could ask the shell for the PID of the spawned child, and monitor its state

How to Send a Password to Process in Java

I am launching a process from java to run a command for me. This process runs for a little while, then needs a password to continue. Now I know that I can write to the in stream of the proces, but I am not quite sure how to detect when I need to write to it.
Possible solutions:
Is there a way that I can detect that the process is blocking?
Can I just write to the standard in immediately after executing the command and when the process hits a point when it needs it, it can just read from it?
Any other ideas?
It is not necessary to detect if the child process is blocking or not. If the child process is designed to block until input is provided to it via stdin, it will block until such input is provided.
It it necessary to keep in mind that the standard input, output and error buffer sizes are limited, and therefore it would be necessary for the child process to process the contents of the input buffer, and for the parent process to process the contents of the output and error buffers as soon as possible. Not doing so will result in the child process hanging.
Maybe you should get around the runas problem but not using runas. Google found me this: http://www.source-code.biz/snippets/c/1.htm Lets you pass your password at runtime....

Categories

Resources