1

I'm practicing java.io methods, so I started by creating a script that prompts the user for a password and prints "correct" if the input is correct. Then, I wrote a java program that executes the script and puts in a password. Then, it outputs the script's output.

import java.lang.*;
import java.io.*;
public class tryIt{
        public static void main(String args[]){
                try{
                        Process apple = Runtime.getRuntime().exec("echo cd|./script");
                        BufferedReader appleRead = new BufferedReader(new InputStreamReader(apple.getInputStream()));
                        String temp = "";
                        String output = "";
                        while((temp = appleRead.readLine())!=null){
                                output += temp;
                        }
                        System.out.println(output);
                }
                catch(Exception e){}

        }
}

In this specific block of code, I am trying to pass the string "cd" as input to the command "./script". However, when I run this java program in Linux, the entire line after the echo statement is printed like this:

cd|./script

I have tried to place some quotes around "cd" and escape them with backslashes, but they get printed as well:

"cd"|./script

When I run this command in the Linux terminal, it works as intended. What can I do to make my program work as intended?

UPDATE: I've changed some of my code to use ProcessBuilder instead of .exec() as suggested:

import java.util.*;
import java.io.*;
public class tryIt{
    public static void main(String[] args){
        try{
          ProcessBuilder process = new ProcessBuilder();
          process.command(new String[]{"echo","cd","|./script"});
          process.directory(new File(System.getProperty("user.dir")));
          BufferedReader read = new BufferedReader(new InputStreamReader(process.start().getInputStream()));
          String hi = "";
          while((hi=read.readLine())!=null){
            System.out.println(hi);
          }
        }
        catch(Exception e){}
        System.out.println("done");
      }
    }

However, the same problem persists. I can't pipe in Bash using the ProcessBuilder so far. Is there any workaround?

  • 2
    Just FYI, from the docs page for `exec()`: *" **Deprecated.** This method is error-prone and should not be used, the corresponding method exec(String[]) or ProcessBuilder should be used instead."* – markspace Mar 22 '23 at 17:43
  • 1
    Does this answer your question? [How to make pipes work with Runtime.exec()?](https://stackoverflow.com/questions/5928225/how-to-make-pipes-work-with-runtime-exec) – Robert Mar 22 '23 at 17:54

1 Answers1

0

Java ProcessBuilder isn't running things via bash, it's running them "directly". So the | is passed as an argument to echo, not to bash.

One option is to actually run bash (i.e. your first argument is /bin/bash instead of echo) and use bash's -c argument. Probably better, just run script.sh via ProcessBuilder and then use Process.OutputStream to send the input (cd) to the script right from Java.

Oliver Dain
  • 9,617
  • 3
  • 35
  • 48
  • Hi, I actually figured this one out by looking at the ProcessBuilder doc! Turns out the ProcessBuilder[].startPipeline() does exactly what I need. Thank you! – TimatoPaste Mar 27 '23 at 19:01