【发布时间】:2014-06-12 08:41:51
【问题描述】:
我想从 Java 执行 bash 命令(在 Linux 系统上)。 我要执行的命令是:
/usr/bin/convert -pointsize 24 label:'Just a test.' ./dummy.png
我第一次使用:
runtime.exec("/usr/bin/convert -pointsize 24 label:'Just a test.' ./dummy.png");
这可行,但使用“Just”作为标签而不是:“Just a test.”。我现在使用:
runtime.exec(new String []{"/usr/bin/convert", "-pointsize 24", "label:'Just a test.'", "./dummy.png"});
这不会报错,但没有生成 dummy.png。
我怎样才能让它工作?
-- 编辑:
在 MadProgrammer 的帮助下,我解决了这个问题。我认为展示一个工作示例是个好主意:
import java.util.Scanner;
import java.io.*;
public class SystemCommand {
// public #########################
public static void main(String[] args) {
try {
doCommand(new String[] {"/usr/bin/convert",
"-background", BACKGROUND,
"-fill", FILL,
"-font", FONT,
"-pointsize", FONTSIZE,
"label:" + CITATION,
FILENAME});
}
catch (IOException e) {
System.out.println(e.getMessage());
}
}
// private ########################
final static String INDENT = " ";
final static String AUTHOR = "Bruce Lee";
final static String BACKGROUND = "NavyBlue";
final static String CITATION =
"\n" +
INDENT + "We all have time to either spend or waste" + INDENT + "\n" +
INDENT + "and it is our decision what to do with it." + INDENT + "\n" +
INDENT + "But once passed, it is gone forever." + INDENT + "\n" +
"\n" +
INDENT + AUTHOR + INDENT + "\n";
final static String FILENAME = "citation.png";
final static String FILL = "Yellow";
final static String FONT = "Bookman-DemiItalic";
final static String FONTSIZE = "24";
static Runtime runtime = Runtime.getRuntime();
private static void doCommand(final String[] cmd) throws IOException {
int i;
Process p;
Scanner sc;
p = runtime.exec(cmd);
sc = new Scanner(p.getInputStream());
while (sc.hasNext()) {
System.out.println(sc.nextLine());
}
}
}
要在 Linux 中测试它(必须安装 Image Magick):
javac SystemCommand.java && java SystemCommand && display citation.png
当我使用 ProcessBuilder 制作示例时,我也会在此处添加它。
-- 编辑
ProcessBuilder 变体。在这种情况下它不是很有用,但是当你做一些更复杂的事情时,它会是一个更好的解决方案。
/*
I needed to write some code that executes something in the Bash shell.
This is not to difficult, but when there are spaces, things can become difficult.
But if you know how it works, then there is no problem.
It can be done Runtime.getRuntime().exec. In this example that would be good enough.
(See SystemCommand.java) But when you have a little bit more difficult things to do,
it is better to use ProcessBuilder. That I do in this example.
The solution is: create a String array in which the first entry is the command
and every parameter has his own entry (without quoutes).
This program is the equavelent of:
/usr/bin/convert -background "NavyBlue" -fill "Yellow" -font "Bookman-DemiItalic" -pointsize 24 label:"
I hope I shall always possess
firmness and virtue enough
to maintain
what I consider the most
enviable of all titles,
the character of an honest man.
George Washington" citation.png
To test it:
javac SystemCommandWithProcessBuilder.java && \
java SystemCommandWithProcessBuilder && \
display citation.png
To use this you need of-course Java, but besides that ImageMagick needs to be installed.
It is written for Linux.
*/
import java.io.*;
public class SystemCommandWithProcessBuilder {
// public #########################
public static void main(String[] args) {
try {
doCommand(new String[] {"/usr/bin/convert",
"-background", BACKGROUND,
"-fill", FILL,
"-font", FONT,
"-pointsize", FONTSIZE,
"label:" + CITATION,
FILENAME});
}
catch (IOException e) {
System.out.println(e.getMessage());
}
}
// private ########################
final static String INDENT = " ";
final static String AUTHOR = "George Washington";
final static String BACKGROUND = "NavyBlue";
final static String CITATION =
"\n" +
INDENT + "I hope I shall always possess" + INDENT + "\n" +
INDENT + "firmness and virtue enough" + INDENT + "\n" +
INDENT + "to maintain" + INDENT + "\n" +
INDENT + "what I consider the most" + INDENT + "\n" +
INDENT + "enviable of all titles," + INDENT + "\n" +
INDENT + "the character of an honest man." + INDENT + "\n" +
"\n" +
INDENT + AUTHOR + INDENT + "\n";
final static String FILENAME = "citation.png";
final static String FILL = "Yellow";
final static String FONT = "Bookman-DemiItalic";
final static String FONTSIZE = "24";
private static void doCommand(final String[] cmd) throws IOException {
BufferedReader br;
String line;
Process p;
p = new ProcessBuilder(cmd).start();
br = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
}
要在 Linux 中测试它(必须安装 Image Magick):
javac SystemCommandWithProcessBuilder.java && \
java SystemCommandWithProcessBuilder && \
display citation.png
【问题讨论】:
-
阅读(并实施)所有 When Runtime.exec() won't 的建议。那可能会解决问题。如果没有,它应该提供更多关于失败原因的信息。然后忽略它引用
exec并使用ProcessBuilder构建Process。还要将String arg分解为String[] args以说明本身包含空格的参数。
标签: java process runtime.exec processbuilder