package za.co.enerweb.toolbox.io;
import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
import za.co.enerweb.toolbox.os.OsUtils;
import za.co.enerweb.toolbox.string.StringUtils;
import za.co.enerweb.toolbox.timing.Stopwatch;
@Slf4j
public class CommandShell extends CommandUtils {
private boolean doneWithExecution = false;
public CommandShell() throws IOException {
if (command == null) {
if (OsUtils.isWindows()) {
command = "cmd.exe";
} else {
command = "/bin/sh";
}
}
start();
}
/**
* mainly for testing
* @param command
* @throws IOException
*/
public CommandShell(final String command) throws IOException {
this.command = command;
start();
}
public void executeInShell(final String cmd) throws IOException {
validateStarted();
cacheOutput();
validateSetup();
doneWithExecution = false;
final String terminatorString = "==" + getClass().getName() + "==";
final OutputHandler terminationWaiter = new OutputHandler() {
@Override
public synchronized void handleLine(final String line) {
if (line.contains(terminatorString)) {
doneWithExecution = true;
notifyAll();
} else {
stdoutHandler.handleLine(line);
}
}
@Override
public void clear() {
}
};
stdoutWaiter.setOutputHandler(terminationWaiter);
stdin.write(cmd + "\n" + "echo " + terminatorString + "\n");
stdin.flush();
while (!doneWithExecution) {
try {
synchronized (terminationWaiter) {
terminationWaiter.wait();
}
} catch (InterruptedException e) {
log.error("Interupted while executing command in shell", e);
}
}
}
// this is useful for manually testing this on different platforms
public static void main(final String[] args) {
if (args.length < 1) {
log.error("USAGE: java za.co.enerweb.toolbox.io.CommandShell "
+ "sping localhost -c 12");
System.exit(1);
}
Stopwatch sw = new Stopwatch();
try {
CommandShell cs = new CommandShell();
log.debug("Start time: {}", sw.getDelta());
cs.executeInShell(StringUtils.join(args, " "));
} catch (IOException e) {
log.error("Error while executing " + args[0], e);
} finally {
log.debug("Execution time: {}", sw.getDelta());
}
}
}