NetUser
NetUser

Reputation: 23

Problem with one command I want to execute through Java in Linux shell

I'm currently working on a Plugin which also can execute commands in the Linux shell. I've setup some commands that I will need later. Killing screens is already working but now I want to start some screen's through my Plugin. But this isn't working.

I've tried to change from Runtime.getRuntime.exec(cmd); to a ProcessBuilder worked for killing screens.

My method to execute commands

public static void shellExecuteBuilder(String[] command, Player p, boolean bool, String Wrapper) {

        ProcessBuilder prb;

        try {
            prb = new ProcessBuilder(command);
            prb.redirectErrorStream(true);
            Process pro = prb.start();
            BufferedReader r = new BufferedReader(new InputStreamReader(pro.getInputStream()));
            String line;
            while (prb.redirectErrorStream() == true) {
                line = r.readLine();
                if (line != null) {
                    System.out.println(line);
                }
            }
            if (bool == true) {
                p.sendMessage("§aDer Wrapper §e" + Wrapper + " §awurde angehalten!");
            } else {
                p.sendMessage("§aDer Wrapper §e" + Wrapper + " §awurde gestartet!");
            }
        } catch (IOException e) {
            if (bool == true) {
                p.sendMessage("§cDer Wrapper §e" + Wrapper + " §ckonnte nicht angehalten werden!");
            } else {
                p.sendMessage("§cDer Wrapper §e" + Wrapper + " §ckonnte nicht gestartet werden!");
            }
            e.printStackTrace();
        }

    }

How I setup this in another method

String[] command = new String[] {"/bin/sh", "-c", "cd /path/to/my/script/", "./start.sh"};

shellExecuteBuilder(command, p, false, Wrapper);

I expected that my method will startup a new screen but it actually does not do anything.

Upvotes: 1

Views: 290

Answers (2)

dave_thompson_085
dave_thompson_085

Reputation: 39029

Alternatively, instead of telling the shell to change directory ProcessBuilder can do it, although not with the way you currently have your program 'factored':

 ProcessBuilder prb = new ProcessBuilder ("/bin/sh", "-c", "./startsh");
 prb.directory("/path/to/my/script");
 prb.redirectErrorStream(true);
 Process pro = prb.start();

or using 'fluent' style all in one statement:

Process pro = new ProcessBuilder ("/bin/sh", "-c", "./startsh")
    .directory("/path/to/my/script").redirectErrorStream(true).start();

Upvotes: 0

schtever
schtever

Reputation: 3250

/bin/sh can accept a sequence of commands, but formatted differently than you have it. Try this instead:

String[] command = new String[] {"/bin/sh", "-c", "cd /path/to/my/script/; ./start.sh"};

Also, the way you process the output from the process will never end. The while loop should be testing the returned output from the process, not the redirection setting (which will never change). Here's a modified version that properly reads the output and wait for the subshell to exit. Note that I removed some of your app's variables (bool, Wrapper, Player) to simplify the example:

import java.io.InputStreamReader;
import java.io.IOException;
import java.io.BufferedReader;

public class TestPB {

    public static void shellExecuteBuilder(String[] command) {

        ProcessBuilder prb;

        try {
            prb = new ProcessBuilder(command);
            prb.redirectErrorStream(true);
            Process pro = prb.start();
            BufferedReader r = new BufferedReader(new InputStreamReader(pro.getInputStream()));
            String line;
            while( (line = r.readLine()) != null) {
                System.out.println(line);
            }
            pro.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static final void main(String[] args) {
        TestPB tpb = new TestPB();
        String[] command = new String[] {"/bin/sh", "-c", "cd /path/to/my/script/; ./start.sh"};
        TestPB.shellExecuteBuilder(command);
    }
}

Upvotes: 1

Related Questions