Reputation: 23
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
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
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