【问题标题】:Using ProcessBuilder with argument list as single String使用带有参数列表的 ProcessBuilder 作为单个字符串
【发布时间】:2023-10-15 18:11:01
【问题描述】:

我尝试从Runtime.exec(command) 切换到ProcessBuilder 以从Java 程序执行ImageMagick 的convert。转换的选项是从用户作为字符串传入的,所以我不能轻易地分离参数以将它们单独传递给ProcessBuilder 的构造函数。在(Unix)命令行上工作的实际命令是

convert -colorspace gray -enhance -density 300 in.pdf out.pdf

我怎样才能让这个可以工作:

public class Demo {
    public static void main(String[] args) throws IOException, InterruptedException {
        String convertOptions = "-colorspace gray -enhance -density 300"; // arguments passed in at runtime
        ProcessBuilder bp = new ProcessBuilder(new String []{"convert",convertOptions,"in.pdf","out.pdf"});
        Process process = bp.start();
        process.waitFor();
    }
}

目前,代码刚刚运行

【问题讨论】:

  • 用“”作为分隔符拆分convertOptions并使用它们来构造convertOptions?如果您传递整个字符串,它将把整个字符串视为一个参数。我想这不是你想要的。
  • 你是对的,但我不需要在“”上拆分,而是在“-”上

标签: java processbuilder


【解决方案1】:

老问题,但因为我面临着类似的情况......

如果您不想将命令字符串拆分为数组,您可以使用bash -c 执行整个字符串:

String convert= "convert -colorspace gray -enhance -density 300";
String[] cmd= new String[] {"bash", "-c", convert};
ProcessBuilder builder = new ProcessBuilder(cmd);
...

这当然假设bash 可用。

【讨论】:

    【解决方案2】:

    您可以使用正则表达式来获取您的参数,如下面的代码:

    String regex = "((\\s*|-)\\w+)";
    Pattern p = Pattern.compile(regex);
    String convertOptions = "-colorspace gray -enhance -density 300"; // //arguments passed in at runtime
    Matcher matcher  = p.matcher(convertOptions);
    List<String> pargs = new ArrayList<String>();
    pargs.add("convert");
    while(matcher.find())
    {
       String match = matcher.group();
       if( match != null )
       {
          pargs.add(match.trim());
       }
    }
    pargs.add("in.pdf");
    pargs.add("out.pdf");
    
    try
    {
        ProcessBuilder bp = new ProcessBuilder( pargs.toArray(new String[]{}) );
        Process process = bp.start();
        process.waitFor();
    }
    catch(Exception ex)
    {
      ex.printStackTrace();
    }
    

    【讨论】:

      最近更新 更多