0

I am a little confused about why I can't run the following command ls -l If I run ls or pwd it works fine.

Am I missing something?

    ProcessBuilder pb = new ProcessBuilder("ls -l");
    pb.redirectErrorStream(true);
    Process process = pb.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);
    }
    br.close();

One more question: How can I run multiple system commands concurrently? Using while loop or for loops will run the command one by one. Any advice?

Thanks in advance.

3
  • 3
    Try new ProcessBuilder("ls", "-l"); Commented Oct 17, 2016 at 0:05
  • Why would you want to?! Use the functionality built into the JDK and keep your code platform independent. Commented Oct 17, 2016 at 0:11
  • to see if it can be done or if it's possible. curious mind wants to know :) Commented Oct 17, 2016 at 0:12

3 Answers 3

1

Change:

new ProcessBuilder("ls -l");

To:

new ProcessBuilder("ls", "-l");
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. One more question. Let's say I have an array of system commands. How should i go about it?
I got it...if anyone's interested here it is
String[] st = {"ls", "bin"}; ProcessBuilder pb = new ProcessBuilder(st);
0
    String[] st = {"ls", "bin"};
    ProcessBuilder pb = new ProcessBuilder(st);
    pb.redirectErrorStream(true);
    Process process = pb.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);
    }
    br.close();  

Comments

0

Using while loop or for loops will run the command one by one.

Only when you are doing the whole start-then-read-stdout business for each one of them, one-by-one. The processes are indeed run in parallel, it's just the reading part that's stopping you from running them concurrently. All you need to do is breaking the start and read into two parts:

    Stream.of(Arrays.asList("ls", "-l"),
              Arrays.asList("python", "-h"),
              Arrays.asList("df"))
            .map(cmd->{
                // Create a process for each command, but don't read the output
                try {
                    return new AbstractMap.SimpleImmutableEntry<>(cmd,
                            new ProcessBuilder(cmd)
                                    .redirectErrorStream(true)
                                    .start().getInputStream());
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            })
            .filter(p->p!=null)
            .parallel()
            .forEach(in->{
                // Read and print STDOUT for each process.
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(in.getValue()))){
                    String line;
                    while ((line = reader.readLine()) != null) {
                        System.out.printf("%20s: %s\n", in.getKey(), line);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });

The parallel() call is making the output really hard to read, it's there only to demonstrate that the processes are really running concurrently.

3 Comments

Thanks for the advice. Need to practice more.
cmd.split("\\s+") takes no accounting for quoting or escaped quotes and is generally a very bad idea.
Thanks, I will modify the answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.