Java Process IO

2019-08-22 01:25发布

Im using java to start a GNOME terminal process in linux and redirecting its input and output to my code. Below is a code.

        public static void main(String[] args) throws InterruptedException
    {
        // TODO Auto-generated method stub  /usr/bin/telnet
        try
        {
            String line, commandInput;
            Scanner scan =  new Scanner(new File("/home/Ashutosh/Documents/testfile"));
            ProcessBuilder telnetProcessBuilder = new ProcessBuilder("/bin/bash");///home/Ashutosh/Documents/tempScript");
            telnetProcessBuilder.redirectErrorStream(true);
            Process telnetProcess = telnetProcessBuilder.start();
            //Process telnetProcess = Runtime.getRuntime().exec("xterm");///home/Ashutosh/Documents/tempScript");
            BufferedReader input = new BufferedReader(new InputStreamReader(telnetProcess.getInputStream()));
            BufferedWriter output = new BufferedWriter(new OutputStreamWriter(telnetProcess.getOutputStream()));
            while(scan.hasNext())
            {
                commandInput = scan.nextLine();
                output.write(commandInput);
/*              if(commandInput.trim().equals("exit"))
                {
                    output.write("exit\r");
                }
                else
                {
                    output.write("((" + commandInput + ") && echo --EOF--) || echo --EOF--\r");
                }
*/              output.flush();
                line = input.readLine();
                while(line != null && !line.trim().equals("--EOF--"))
                {
                    System.out.println(line);
                    line = input.readLine();
                }
                if(line == null)
                    break;
            }
/*          Thread.sleep(500);
            output.write("/home/Ashutosh/Documents/testfile\r");
            Thread.sleep(500);
            output.flush();

            while((line = input.readLine())!= null)
                System.out.println(line);
            telnetProcess.destroy();
*/          //String s = input.readLine();
            //System.out.print(s + "\r\n");
            //s = input.readLine();
            //System.out.print(s + "\r\n");
        }

the contents of testfile which is bash script is

#!/bin/bash

ls -l
pwd
date
exit

and i also tried the following interactive script which takes input from user which i want to redirect from java code is given

#! /bin/bash
echo "Input any number form 0-3:"
read num
case $num in
  0) echo "You are useless";;
  1) echo "You are number 1";;
  2) echo "Too suspecious";;
  3) echo "Thats all man, got to go...!";;
  *) echo "Cant't u read english, this is wrong choice";;
esac
read
exit

my code stops at input.readLine(); im not sure but i think i am not able to redirect the output stream

output.write(commandInput);

command is executing well but did not write i intended to on the process redirected input, that is why it hangs at readLine();. If somebody have already solved please let me know the solution. From following link i tried to solve the issue but still no luck:

Java Process with Input/Output Stream

Thanks

Ashutosh

标签: java linux
3条回答
我想做一个坏孩纸
2楼-- · 2019-08-22 01:32

EDIT: Huge error, not adding the command to the ProcessBuilder!!

Why are you not just running your script as a Linux script? That is,

ProcessBuilder builder = new ProcessBuilder();
LinkedList<String> command = new LinkedList<String>();
command.add("/bin/bash");
command.add("/home/Ashutosh/Documents/testfile");
builder.command(command);

Process myProc = builder.start();

Also, I notice the variable is named 'telnetProcess' yet there is no invocation of telnet anywhere that I can see. Perhaps this is the problem?

EDIT: Added my suggestion below for the interactive script.

ProcessBuilder builder = new ProcessBuilder();
LinkedList<String> command = new LinkedList<String>();
command.add("/bin/bash");
command.add("/path/to/interactiveScript");
builder.command(command);

final Process myProc = builder.start();

// Java input goes to process input.
Thread inputParser = new Thread() {
  public void run() {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(myProc.getOutputStream()));
    String line = "";
    while(line != null) {
      line = br.readLine();
      bw.write(line);
      bw.newLine();
    }
  }
}.start();

// Process output must go to Java output so user can see it!
Thread outputParser = new Thread() {
  public void run() {  
    BufferedReader br = new BufferedReader(new InputStreamReader(myProc.getInputStream()));
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    String line = "";
    while(line != null) {
      line = br.readLine();
      bw.write(line);
      bw.newLine();
    }
  }
}.start();
查看更多
倾城 Initia
3楼-- · 2019-08-22 01:37

hi guys sorry for late response, after some trials i got it working. I am simply letting the process completing its process and exit normally rather than forcefully and then the BufferedReader and BufferedWriter keeps the string buffers in RAM which i can read now after process exit with code 0.

public static void main(String[] args) throws InterruptedException
{
    // TODO Auto-generated method stub
    try
    {
        String line, commandInput;
        ProcessBuilder telnetProcessBuilder = new ProcessBuilder("/bin/bash");
        telnetProcessBuilder.redirectErrorStream(true);
        Process telnetProcess = telnetProcessBuilder.start();
        BufferedReader input = new BufferedReader(new InputStreamReader(telnetProcess.getInputStream()));
        BufferedWriter output = new BufferedWriter(new OutputStreamWriter(telnetProcess.getOutputStream()));
        commandInput = "ls -l\n";
        output.write(commandInput);
        output.flush();
        commandInput = "pwd\n";
        output.write(commandInput);
        output.flush();
        commandInput = "whoami\n";
        output.write(commandInput);
        output.flush();
        commandInput = "exit\n";
        output.write(commandInput);
        output.flush();
        while((line = input.readLine())!= null)
            System.out.println(line);
    }
}
查看更多
Summer. ? 凉城
4楼-- · 2019-08-22 01:55

readLine() read the contents of a line, without the newline at the end.

write() writes just the text, it doesn't add a new line.

Perhaps you want to add write("\n"); or use PrintStream or PrintWriter.

I imagine, your script is being sent as

#!/bin/bashls -lpwddateexit

which is a comment without a newline.

查看更多
登录 后发表回答