【问题标题】:command fails from exec() but works on terminal命令从 exec() 失败,但在终端上工作
【发布时间】:2015-04-10 08:04:44
【问题描述】:

我正在尝试使用 Java 将 pdf 转换为 txt。我尝试过 Apache PDFBox,但由于某些奇怪的原因,它并没有转换整个文档。出于这个原因,我决定通过执行 Runtime.getRuntime().exec() 调用来使用 pdftotext。问题是,虽然我的终端 pdftotext 完美运行,但 exec() 调用给了我错误代码 1(有时甚至是 99)。 这是电话:

pdftotext "/home/www-data/CANEFS_TEST/Hello/ciao.pdf" "/tmp/ciao.pdf.txt"

这是代码

private static File callPDF2Text(File input,File output){
    assert input.exists();
    assert Utils.getExtension(input).equalsIgnoreCase("pdf");
    assert Utils.getExtension(output).equalsIgnoreCase("txt") : output.getAbsoluteFile().toString();

    Process p=null;

    try {
        System.out.println(String.format(
                PDF2TXT_COMMAND,
                input.getAbsolutePath(),
                output.getAbsolutePath()));
        p=Runtime.getRuntime().exec(String.format(
                PDF2TXT_COMMAND,
                input.getAbsolutePath(),
                output.getAbsolutePath()));
        p.waitFor();
        if (p.exitValue()!=0){
            throw new RuntimeException("exit value for pdftotext is "+p.exitValue());
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

    return output;
}

这里是 PDF2TXT_COMMAND 字符串定义:

public static final String PDFTXT_COMMAND="pdftotext \"%s\" \"%s\"";

我知道这些错误通常是由权限设置引起的。所以,这里是 Hello 文件夹上 ls -l 命令的输出:

ls -l /home/www-data/CANEFS_TEST/Hello/
total 136
-rwxrwxr-- 1 www-data www-data 136041 mar 27 16:31 ciao.pdf

另外,请注意创建进程的用户是 koldar,它位于组 www-data 本身中。 感谢您的时间和耐心!

【问题讨论】:

    标签: java linux runtime.exec pdftotext


    【解决方案1】:

    不要在格式字符串中使用 "... 这些字符由 shell 专门解析,您不使用 shell 来启动命令...

    我可以建议你使用exec(String []) 而不是exec(String),这样你就可以分隔你的命令的每个参数:

    String []command = new String[3];
    command[0] = "pdftotext";
    command[1] = input.getAbsolutePath();
    command[2] = output.getAbsolutePath();
    Runtime.getRuntime().exec(command);
    

    应该可以。如果不是,那可能是 dir 的访问权限问题。

    【讨论】:

    • 好的,这行得通,但是如果 pdf 文件名中包含空格会怎样?没关系……它也有效!非常感谢!
    • 这保证有效!每个参数都将按原样传递给系统!你不得不在 shell 中使用 " ,因为你想说:这是一个单一的参数。使用 exec(String []) 绕过任何解析。
    • 这确实是一个非常愚蠢的问题。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2020-07-28
    • 2021-01-06
    • 2013-12-28
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    • 1970-01-01
    相关资源
    最近更新 更多