runtime.exec,参数中包含空格

时间:2014-06-12 08:41:52

标签: java process runtime.exec processbuilder

我想从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”作为标签而不是:“只是一个测试。”。我现在用:

    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

我已在https://github.com/CecilWesterhof/JavaExamples

发表了这两篇文章

1 个答案:

答案 0 :(得分:1)

首先,使用ProcessBuilder简化整个过程

话虽如此,String数组中的每个元素都被视为命令的单个参数,也就是说,这正是命令args[]数组的外观。

您可以尝试类似......

runtime.exec(new String []{"/usr/bin/convert", "-pointsize", "24", "label:'Just a test.'", "./dummy.png"})