下面列出了怎么用java.lang.ProcessBuilder.Redirect的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void givenProcessBuilder_whenRedirectStandardOutput_thenSuccessAppending() throws IOException, InterruptedException {
ProcessBuilder processBuilder = new ProcessBuilder("java", "-version");
File log = tempFolder.newFile("java-version-append.log");
processBuilder.redirectErrorStream(true);
processBuilder.redirectOutput(Redirect.appendTo(log));
Process process = processBuilder.start();
assertEquals("If redirected output, should be -1 ", -1, process.getInputStream()
.read());
int exitCode = process.waitFor();
assertEquals("No errors should be detected", 0, exitCode);
List<String> lines = Files.lines(log.toPath())
.collect(Collectors.toList());
assertThat("Results should not be empty", lines, is(not(empty())));
assertThat("Results should contain java version: ", lines, hasItem(containsString("java version")));
}
private void installPlugin(File pluginManager, InstallationDescription.Plugin plugin) throws IOException, InterruptedException {
logger.info("> " + pluginManager + " install " + plugin.getExpression());
ProcessBuilder builder = new ProcessBuilder();
builder.redirectOutput(Redirect.PIPE);
builder.redirectErrorStream(true);
builder.command(prepareInstallCommand(pluginManager, plugin));
Process process = builder.start();
BufferedReader bReader = new BufferedReader(new InputStreamReader(process.getInputStream(), UTF_8));
String line;
while ((line = bReader.readLine()) != null) {
logger.info(String.format("Plugin install %s: %s", plugin, line));
}
if (process.waitFor() != 0) {
throw new EmbeddedElasticsearchStartupException("Unable to install plugin: " + plugin);
}
}
/**
* Returns a {@link ProcessBuilder.Redirect} appropriate for the parameters. If a file redirected
* to exists, deletes the file before redirecting to it.
*/
private Redirect getRedirect(StreamAction action, File file) {
switch (action) {
case DISCARD:
return Redirect.to(new File("/dev/null"));
case REDIRECT:
// We need to use Redirect.appendTo() here, because on older Linux kernels writes are
// otherwise not atomic and might result in lost log messages:
// https://lkml.org/lkml/2014/3/3/308
if (file.exists()) {
file.delete();
}
return Redirect.appendTo(file);
case STREAM:
return Redirect.PIPE;
default:
throw new IllegalStateException();
}
}
public void receive(Path destinationPath, Consumer<OutputStream> callback) {
try {
Process process = processBuilder("btrfs", "receive", "-e",
destinationPath.toAbsolutePath().toString())
.redirectOutput(Redirect.PIPE).start();
callback.consume(process.getOutputStream());
process.getOutputStream().close();
int exitValue = process.waitFor();
if (exitValue != 0) {
throw new IOException("exit code: " + exitValue);
}
}
catch (IOException | InterruptedException e) {
throw new RuntimeException(
"Error while receiving snapshot sub volume in "
+ destinationPath, e);
}
}
public void run() {
ArrayList<String> cmd = new ArrayList<>();
cmd.add("ffmpeg"); // binary should be on path
cmd.add("-y"); // always overwrite files
cmd.add("-f"); // format
cmd.add("avfoundation"); // apple's system audio---something else for windows
cmd.add("-i"); // input
cmd.add(":" + deviceId); // device id returned by ffmpeg list
cmd.add(captureFile.getAbsolutePath());
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
pb.redirectOutput(Redirect.PIPE);
StringJoiner out = new StringJoiner("\n");
try {
proc = pb.start();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(proc.getInputStream()))) {
reader.lines().forEach(out::add);
}
proc.waitFor();
} catch (IOException | InterruptedException ign) {}
System.out.println("FFMpeg output was: " + out.toString());
}
private ProcessBuilder prepareBuilder(
ProcessBuilder builder, SubProcessCommandLineArgs commands, SubProcessIOFiles outPutFiles)
throws IllegalStateException {
// Check we are not over the max size of command line parameters
if (getTotalCommandBytes(commands) > MAX_SIZE_COMMAND_LINE_ARGS) {
throw new IllegalStateException("Command is over 2MB in size");
}
appendExecutablePath(builder);
// Add the result file path to the builder at position 1, 0 is reserved for the process itself
builder.command().add(1, outPutFiles.resultFile.toString());
// Shift commands by 2 ordinal positions and load into the builder
for (SubProcessCommandLineArgs.Command s : commands.getParameters()) {
builder.command().add(s.ordinalPosition + 2, s.value);
}
builder.redirectError(Redirect.appendTo(outPutFiles.errFile.toFile()));
builder.redirectOutput(Redirect.appendTo(outPutFiles.outFile.toFile()));
return builder;
}
public void start(final String processName) throws IOException {
final Config config = Config.load(this.configFilePath);
final Path workPath = config.workDir();
final List<String> params = Lists.newArrayList();
params.add(executableLocation());
params.add(configFilePath.toString());
final ProcessBuilder processBuilder = new ProcessBuilder(params)
.directory(new File(System.getProperty("user.dir")))
.redirectErrorStream(true)
.redirectInput(Redirect.INHERIT);
try {
final Process process = processBuilder.start();
outputProcessorExecutor.submit(() -> printOutput(processName, process));
processes.put(processName, process);
} catch (final IOException e) {
LOG.error("Error starting Orion process", e);
}
loadPortsFile(workPath);
}
public Process startSecondJVM(Class<?> mainClassToStart) throws IOException {
String separator = System.getProperty("file.separator");
String classpath = System.getProperty("java.class.path");
String path = System.getProperty("java.home") + separator + "bin"
+ separator + "java";
ProcessBuilder processBuilder = new ProcessBuilder(path, "-Xdebug",
"-Xrunjdwp:transport=dt_socket,address=" + debugPort
+ ",server=y,suspend=y", "-cp", classpath,
mainClassToStart.getCanonicalName());
processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
final Process process = processBuilder.start();
Thread closeChildThread = new Thread() {
public void run() {
process.destroy();
}
};
Runtime.getRuntime().addShutdownHook(closeChildThread);
return process;
}
/**
* Returns a {@link java.lang.ProcessBuilder.Redirect} appropriate for the parameters. If a file
* redirected to exists, deletes the file before redirecting to it.
*/
private Redirect getRedirect(StreamAction action, File file) {
switch (action) {
case DISCARD:
return Redirect.to(new File("/dev/null"));
case REDIRECT:
// We need to use Redirect.appendTo() here, because on older Linux kernels writes are
// otherwise not atomic and might result in lost log messages:
// https://lkml.org/lkml/2014/3/3/308
if (file.exists()) {
file.delete();
}
return Redirect.appendTo(file);
case STREAM:
return Redirect.PIPE;
default:
throw new IllegalStateException();
}
}
@Test
public void exitIfChangedFiles() throws Exception {
Path path = testFolder.newFile("Test.java").toPath();
Files.write(path, "class Test {\n}\n".getBytes(UTF_8));
Process process =
new ProcessBuilder(
ImmutableList.of(
Paths.get(System.getProperty("java.home")).resolve("bin/java").toString(),
"-cp",
System.getProperty("java.class.path"),
Main.class.getName(),
"-n",
"--set-exit-if-changed",
path.toAbsolutePath().toString()))
.redirectError(Redirect.PIPE)
.redirectOutput(Redirect.PIPE)
.start();
process.waitFor();
String err = new String(ByteStreams.toByteArray(process.getErrorStream()), UTF_8);
String out = new String(ByteStreams.toByteArray(process.getInputStream()), UTF_8);
assertThat(err).isEmpty();
assertThat(out).isEqualTo(path.toAbsolutePath().toString() + System.lineSeparator());
assertThat(process.exitValue()).isEqualTo(1);
}
private static List<String> runCmd(List<String> args) {
List<String> lines = new ArrayList<>();
ProcessBuilder builder = new ProcessBuilder(args);
builder.redirectOutput(Redirect.PIPE).redirectErrorStream(true);
try {
boolean hadMsg = false;
Process process = builder.start();
try (BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
String line = in.readLine();
while (line != null) {
lines.add(line);
line = in.readLine();
}
}
} catch (IOException exception) {
System.out.println();
exception.printStackTrace(System.err);
System.exit(1);
}
return lines;
}
private ProcessBuilder processBuilder(SshTarget target,
List<String> commands) {
// construct command
LinkedList<String> list = new LinkedList<String>();
list.add("ssh");
// add port
if (target.getPort() != null) {
list.add("-p");
list.add(target.getPort().toString());
}
// add host
list.add(target.getHost());
// add commands
list.addAll(commands);
return new ProcessBuilder().redirectError(Redirect.INHERIT).command(
list);
}
/** Run shell script with command line arguments */
public static void runScript(final String cmd[], final File outFile) {
try {
final ProcessBuilder pb = new ProcessBuilder(cmd);
if (outFile != null)
pb.redirectOutput(outFile);
else
pb.redirectOutput(Redirect.INHERIT);
pb.redirectError(Redirect.INHERIT);
final Process process = pb.start();
process.waitFor();
process.destroy();
} catch (final Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder ls = new ProcessBuilder()
.command("tree", "-i")
.directory(Paths.get("/home/nipa").toFile());
ProcessBuilder grepPdf = new ProcessBuilder()
.command("grep", "pdf")
.redirectOutput(Redirect.INHERIT);
List<Process> lsThenGrep = ProcessBuilder.startPipeline(asList(ls, grepPdf));
System.out.println("Started processes...");
CompletableFuture[] lsThenGrepFutures = lsThenGrep.stream()
// onExit returns a CompletableFuture<Process>
.map(Process::onExit)
.map(processFuture -> processFuture.thenAccept(
process -> System.out.println("Process " + process.pid() + " finished.")))
.toArray(CompletableFuture[]::new);
// wait until all processes are finished
CompletableFuture
.allOf(lsThenGrepFutures)
.join();
}
private ProcessBuilder prepareBuilder(
ProcessBuilder builder, SubProcessCommandLineArgs commands, SubProcessIOFiles outPutFiles)
throws IllegalStateException {
// Check we are not over the max size of command line parameters
if (getTotalCommandBytes(commands) > MAX_SIZE_COMMAND_LINE_ARGS) {
throw new IllegalStateException("Command is over 2MB in size");
}
appendExecutablePath(builder);
// Add the result file path to the builder at position 1, 0 is reserved for the process itself
builder.command().add(1, outPutFiles.resultFile.toString());
// Shift commands by 2 ordinal positions and load into the builder
for (SubProcessCommandLineArgs.Command s : commands.getParameters()) {
builder.command().add(s.ordinalPosition + 2, s.value);
}
builder.redirectError(Redirect.appendTo(outPutFiles.errFile.toFile()));
builder.redirectOutput(Redirect.appendTo(outPutFiles.outFile.toFile()));
return builder;
}
private void start(ProcessBuilder builder, Path workDir, boolean deleteOnExit) throws IOException {
String workDirPath = workDir.toFile().getAbsolutePath();
this.stdout = Files.createFile(Paths.get(workDirPath, "stdout_" + instanceNumber + ".log")).toFile();
this.attributes.put("stdout", stdout.getAbsolutePath());
this.stderr = Files.createFile(Paths.get(workDirPath, "stderr_" + instanceNumber + ".log")).toFile();
this.attributes.put("stderr", stderr.getAbsolutePath());
if (deleteOnExit) {
this.stdout.deleteOnExit();
this.stderr.deleteOnExit();
}
builder.redirectOutput(Redirect.to(this.stdout));
builder.redirectError(Redirect.to(this.stderr));
this.start(builder, workDir);
}
@Test
public void exitIfChangedStdin() throws Exception {
Path path = testFolder.newFile("Test.java").toPath();
Files.write(path, "class Test {\n}\n".getBytes(UTF_8));
Process process =
new ProcessBuilder(
ImmutableList.of(
Paths.get(System.getProperty("java.home")).resolve("bin/java").toString(),
"-cp",
System.getProperty("java.class.path"),
Main.class.getName(),
"-n",
"--set-exit-if-changed",
"-"))
.redirectInput(path.toFile())
.redirectError(Redirect.PIPE)
.redirectOutput(Redirect.PIPE)
.start();
process.waitFor();
String err = new String(ByteStreams.toByteArray(process.getErrorStream()), UTF_8);
String out = new String(ByteStreams.toByteArray(process.getInputStream()), UTF_8);
assertThat(err).isEmpty();
assertThat(out).isEqualTo("<stdin>" + System.lineSeparator());
assertThat(process.exitValue()).isEqualTo(1);
}
public static void exec(Consumer<Character> charConsumer, String... command) {
File tempFile = null;
try {
tempFile = File.createTempFile("sdk", "log");
logger.debug("Command to be executed: {}", (Object) command);
String[] commands = new String[command.length + 2];
commands[0] = getBash();
commands[1] = "-c";
System.arraycopy(command, 0, commands, 2, command.length);
ProcessBuilder pb = new ProcessBuilder(commands)
.directory(new File("."))
.redirectErrorStream(true)
.redirectOutput(Redirect.to(tempFile));
Process process = pb.start();
OutputStream outputStream = process.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream);
// say yes
printWriter.write("n\n");
printWriter.flush();
try (InputStreamReader isr = new InputStreamReader(new FileInputStream(tempFile))) {
while (process.isAlive()) {
int ch = isr.read();
if (ch < 0) {
Thread.sleep(10);
continue;
}
charConsumer.accept((char) ch);
}
}
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
} finally {
if (tempFile != null && tempFile.exists()) {
if (!tempFile.delete()) {
logger.warn("Failed to delete {} even though it exists, try deleteOnExit", tempFile);
tempFile.deleteOnExit();
}
}
}
}
private void execute(String command, File directory)
throws Exception {
System.out.println("$ " + command);
ProcessBuilder pb = new ProcessBuilder(command.split(" "));
pb.directory(directory);
pb.redirectErrorStream(true);
pb.redirectOutput(Redirect.INHERIT);
Process p = pb.start();
p.waitFor();
}
@Override
public Process launch(String program, List<String> args) throws IOException {
List<String> arguments = new ArrayList<>();
arguments.add(program);
arguments.addAll(args);
ProcessBuilder processBuilder =
new ProcessBuilder()
.command(arguments)
.redirectErrorStream(true)
.redirectOutput(Redirect.PIPE);
return processBuilder.start();
}
@Test
public void testLaunch() throws Exception {
List<String> args = new ArrayList<>();
args.add("arg1");
args.add("arg2");
ProcessBuilder processBuilder = PowerMock.createMock(ProcessBuilder.class);
PowerMock.expectNew(ProcessBuilder.class, new Class[] {}).andReturn(processBuilder);
Capture<List<String>> captureCommands = Capture.newInstance();
expect(processBuilder.command(capture(captureCommands))).andReturn(processBuilder);
expect(processBuilder.redirectErrorStream(true)).andReturn(processBuilder);
expect(processBuilder.redirectOutput(Redirect.PIPE)).andReturn(processBuilder);
Process process = mock(Process.class);
expect(processBuilder.start()).andReturn(process);
PowerMock.replayAll(ProcessBuilder.class, processBuilder);
assertEquals(process, processLauncher.launch("program-name", args));
PowerMock.verify(ProcessBuilder.class, processBuilder);
List<String> commands = captureCommands.getValue();
assertEquals(3, commands.size());
assertEquals("program-name", commands.get(0));
assertEquals("arg1", commands.get(1));
assertEquals("arg2", commands.get(2));
}
public void restart() {
ProcessBuilder builder = new ProcessBuilder();
if (config.startScript != null) builder.command(Collections.singletonList(config.startScript));
else throw new IllegalArgumentException("Please create start script and link it as startScript in config.");
builder.directory(this.dir.toFile());
builder.inheritIO();
builder.redirectErrorStream(true);
builder.redirectOutput(Redirect.PIPE);
try {
builder.start();
} catch (IOException e) {
LogHelper.error(e);
}
}
/**
* Returns a new default executor that will delegate execution to {@link Runtime#exec(String[], String[], File)}.
* This executor is mainly intended for headless case, but may be useful in the UI case as well. However, the main
* executor to be used in the UI case is returned by method <code>RunnerFrontEndUI#createUIExecutor()</code>.
*/
public IExecutor createDefaultExecutor() {
return new IExecutor() {
@Override
public Process exec(String[] cmdLine, File workingDirectory, Map<String, String> envp)
throws ExecutionException {
ProcessBuilder pb = new ProcessBuilder(cmdLine);
pb.environment().putAll(envp);
pb.directory(workingDirectory);
pb.inheritIO();
// Special case for running from Java-code & capturing output of run-result:
String errFile = System.getProperty("org.eclipse.n4js.runner.RunnerFrontEnd.ERRORFILE", "");
String outFile = System.getProperty("org.eclipse.n4js.runner.RunnerFrontEnd.OUTPUTFILE", "");
if (errFile != null && errFile.length() > 0) {
pb.redirectError(Redirect.to(new File(errFile)));
}
if (outFile != null && outFile.length() > 0) {
pb.redirectOutput(Redirect.to(new File(outFile)));
}
try {
return pb.start();
} catch (IOException e) {
throw new ExecutionException(e);
}
}
};
}
public ProcessRunner ( final ProcessBuilder processBuilder )
{
this.processBuilder = processBuilder;
processBuilder.redirectError ( Redirect.INHERIT );
processBuilder.redirectOutput ( Redirect.INHERIT );
processBuilder.redirectInput ( Redirect.INHERIT );
}
private ProcessBuilder processBuilder(LinkedList<String> list) {
if (useStrace()) {
list.addFirst("-ff");
list.addFirst("strace." + MDC.get("id") + ".log");
list.addFirst("-o");
list.addFirst("strace");
}
if (useSudo()) {
list.addFirst("sudo");
}
log.debug("created process builder: " + list);
return new ProcessBuilder().redirectError(Redirect.INHERIT)
.redirectOutput(Redirect.INHERIT).command(list);
}
@Override
public IQData start() throws InterruptedException {
File rawFile = new File(config.getTempDirectory(), req.getSatelliteId() + "-" + req.getId() + ".raw.gz");
Long startTimeMillis = null;
Long endTimeMillis = null;
try {
Integer ppm = config.getInteger("ppm.current");
if (ppm == null) {
ppm = 0;
}
startTimeMillis = System.currentTimeMillis();
rtlSdr = factory.create(config.getProperty("satellites.rtlsdrwrapper.path") + " -rtl " + config.getProperty("satellites.rtlsdr.path") + " -f " + req.getActualFrequency() + " -s " + req.getInputSampleRate() + " -g " + config.getProperty("satellites.rtlsdr.gain") + " -p " + ppm + " -o " + rawFile.getAbsolutePath(), Redirect.INHERIT, false);
int responseCode = rtlSdr.waitFor();
// rtl_sdr should be killed by the reaper process
// all other codes are invalid. even 0
if (responseCode != 143) {
LOG.error("[{}] invalid response code rtl_sdr: {}", req.getId(), responseCode);
Util.deleteQuietly(rawFile);
} else {
LOG.info("[{}] rtl_sdr stopped: {}", req.getId(), responseCode);
}
} catch (IOException e) {
LOG.error("[{}] unable to run", req.getId(), e);
} finally {
endTimeMillis = System.currentTimeMillis();
}
IQData result = new IQData();
result.setActualStart(startTimeMillis);
result.setActualEnd(endTimeMillis);
if (rawFile.exists()) {
result.setDataFile(rawFile);
}
return result;
}
public ProcessWrapper create(String commandLine, Redirect redirectError, boolean inheritIO) throws IOException {
LOG.info("started with arguments: {}", commandLine);
ProcessBuilder processBuilder = new ProcessBuilder(SPACE.split(commandLine));
if (redirectError != null) {
processBuilder.redirectError(redirectError);
}
if (inheritIO) {
processBuilder.inheritIO();
}
return new ProcessWrapperImpl(processBuilder.start());
}
private void copyLogTail() {
if (configuration.getTailLogLinesToSave() <= 0) {
return;
}
final Path tailOfLogPath = taskDefinition.getServiceFinishedTailLogPath();
if (Files.exists(tailOfLogPath)) {
log.debug("{} already existed, skipping tail", tailOfLogPath);
return;
}
final List<String> cmd = ImmutableList.of(
"tail",
"-n",
Integer.toString(configuration.getTailLogLinesToSave()),
taskDefinition.getServiceLogOut()
);
try {
new SimpleProcessManager(log).runCommand(cmd, Redirect.to(tailOfLogPath.toFile()));
} catch (Throwable t) {
log.error(
"Failed saving tail of log {} to {}",
taskDefinition.getServiceLogOut(),
taskDefinition.getServiceFinishedTailLogPath(),
t
);
}
}
public List<String> runCommandWithOutput(
final List<String> command,
final Set<Integer> acceptableExitCodes
)
throws InterruptedException, ProcessFailedException {
return runCommand(command, Redirect.PIPE, acceptableExitCodes);
}
public List<String> runCommand(
final List<String> command,
final Redirect redirectOutput
)
throws InterruptedException, ProcessFailedException {
return runCommand(command, redirectOutput, Sets.newHashSet(0));
}