1

I have a java app that runs a bash file and inside the bash file i have a code to run another java app and it doesn't seem to work.I come from c++ where this is a very easy task but i'm not really experienced in java. So, here's my code:

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class start {

public void executeScript(){
    try{
        ProcessBuilder pb = new ProcessBuilder("/root/Desktop/chat/script.sh");
        Process p = pb.start();
        p.waitFor();
        System.out.println("Script executed..");
    }catch(Exception e){
        e.printStackTrace();
        }

}

public static void main(String[] args) {
    start st = new start();
    System.out.println("I'm main..");
    st.executeScript();
}

}

Here's my bash file:

#!/bin/bash
echo "bash started"
java Client ip_address
echo "bash finished"

Here's the result of this code:

I'm main.. Script executed..

I know "Script executed.." shouldn't print because the java file i'm trying to run from the bash file is an infinite loop.

Note: If i run the bash file separately in the terminal i get an infinite loop which is the intended result and this is why i know that my mistake is from this file.

I hope I made myself clear and if not please ask for more information. Thank you.

3
  • Add some echo commands to the bash script so you see how far it gets. Commented Mar 29, 2018 at 14:24
  • @ArndtJonasson I tried that before and the echos are not displayed in the terminal. Commented Mar 29, 2018 at 14:27
  • I use Runtime.getRuntime().exec to create processes, maybe that will help. Also, the echos should be captured in the input stream of the process (see stackoverflow.com/questions/15801069/… for how to print out the results) Commented Mar 29, 2018 at 14:43

3 Answers 3

5

Another way of doing would be to use Runtime.getRuntime(). Something like this

  public void executeScript() throws IOException, InterruptedException {
    Process p = Runtime.getRuntime().exec("sh /root/Desktop/chat/script.sh");
    p.waitFor();

    BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
    BufferedReader errorReader = new BufferedReader(new InputStreamReader(p.getErrorStream()));


    String line = "";
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }

    line = "";
    while ((line = errorReader.readLine()) != null) {
        System.out.println(line);
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

I used this and now the echo statements are printed but still i can't run the file Client!
@John123 I have made a minor edit which would enable you to also get the error result. I guess is, "Client" is not in the right location. Just do a "pwd" and make sure it is in the right path.
This is the output now: I'm main.. bash started bash finished Error: Could not find or load main class Client This is weird because as i said before if i run the client separately it works normally!
1

With the above test you can not guaranty that whether it is running or not. Because clearly you told that your are running a infinite loop inside your second java application. Now my advise would be to put some System.out.println statement inside that infinite loop and use below java code to execute your shell script. Here in the output.txt file you can see the output from your shell script as well as java program and you will know whether application executed successfully or not. Also put some echo statement inside your shell script as well.

 String[] command ={"/root/Desktop/chat/script.sh", "command line param if any"};
    ProcessBuilder pb = new ProcessBuilder(command);

    pb.redirectOutput(new File("/tmp/output.txt"));
    String result;
    String overall="";
    try {
        Process p = pb.start();
        p.waitFor();
        BufferedReader br = new BufferedReader(
                new InputStreamReader(p.getInputStream()));
            while ((result = br.readLine()) != null){
                overall = overall + "\n" + result;
            }
            p.destroy();
            System.out.println(result);

    } catch (Exception e) {
        e.printStackTrace();
    }

2 Comments

I added an getErrorStream() and i got this output in the file: I'm main.. bash started bash finished Error: Could not find or load main class Client
Your problem is with java class path. Inside the shell script set the class path before executing the java application.
-1

if you start a process like you wrote Process p = pb.start(); it will make(we usually say fork) one more process from the java process.

  1. for example, java is running as a process 'A'

  2. and if the process 'A' starts another process 'B'

  3. then those are running at the same time.

    (in your case, A is 'JAVA' and B is 'Shell')

so, it will be 2. and the 2 processes are running in the same time (parallely), so you will get two of those results at the same time.

1 Comment

But i guess this is why i used p.waitFor() ; because now process A will not start until process B is finished?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.