Вызов сценария perl из сервлета Java

Я пытаюсь вызвать Perl-скрипт из java-сервлета на tomcat 7. Я настроил context.xml и web.xml, чтобы запустить файл .pl, перейдя в http://localhost:8080/test/cgi-bin/test.pl, и я также могу запускать Perl прямо изнутри java вот так:

String[] cmdArr = new String[]{"perl", "-e", "print \"Content-type: text/html\n\n\";$now = localtime();print \"<h1>It is $now</h1>\";"};
if (cmdArr != null) {
        Process p = null;
        Runtime rt = Runtime.getRuntime();
        try {
            p = rt.exec(cmdArr);  // throws IOException
            returnValue = p.waitFor();    // throws InterruptedException
        }
        catch (IOException xIo) {
            throw new RuntimeException("Error executing command.",xIo);
        }
        catch (InterruptedException xInterrupted) {
            throw new RuntimeException("Command execution interrupted.",xInterrupted);
        }

        InputStreamReader isr = new InputStreamReader(p.getInputStream());
        BufferedReader stdout = null;
        stdout = new BufferedReader(isr);
        String line = null;
        try {
            while ((line = stdout.readLine()) != null) {
                System.out.println(line);
            }
        }
        catch (IOException xIo) {
            throw new RuntimeException("Error reading process output", xIo);
        }
    }

и это работает нормально, но если я попытаюсь сослаться на сценарий .pl, который находится в моей папке / WEB-INF / cgi, заменив:

String[] cmdArr = new String[]{"perl", "-e", "print \"Content-type: text/html\n\n\";$now = localtime();print \"<h1>It is $now</h1>\";"};

с чем-то вроде:

String cmdArr = "/WEB-INF/cgi/test.pl";

or

String cmdArr = "/cgi-bin/test.pl";

Я все время получаю эту ошибку:

java.io.IOException: Cannot run program "/WEB-INF/cgi/test.pl": error=2, No such file or directory

Я предполагаю, что я где-то ошибаюсь с путем к файлу? Любая помощь могла бы быть полезна!


ОБНОВЛЕНИЕ: после комментария @hobbs я изменился на: String[] cmdArr = new String[]{"perl", "/WEB-INF/cgi/test.pl"};

но если я добавлю следующее перед .waitFor ():

 BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
 String line;
 while ( (line = br.readLine()) != null){
       System.out.println(line);
 }

Я получаю отпечаток:

Can't open perl script "/WEB-INF/cgi/test.pl": No such file or directory 

Я думаю, это возвращение к исходной проблеме?


person DFSOKO    schedule 10.10.2011    source источник


Ответы (2)


Несколько сбивает с толку, когда системный вызов exec возвращает «Нет такого файла или каталога» в сценарии, это обычно означает, что интерпретатор в строке shebang не может быть найден. например если /WEB-INF/cgi-test.pl начинается с #!/usr/bin/perl, возможно, / usr / bin / perl не существует. Или, если файл имеет окончания строки Windows, это может привести к тому, что ядро ​​будет искать интерпретатор с именем "/usr/bin/perl\x0a", который не может быть найден.

Поскольку вы установили, что можете запускать что-либо, используя массив команд, который начинается с "perl", как насчет:

String cmdArr = new String[]{"perl", "/WEB-INF/cgi/test.pl"};

?

person hobbs    schedule 10.10.2011
comment
Большое спасибо @hobbs! ваш правый /WEB-INF/cgi/test.pl начался с #! / usr / bin / perl, ваше предложение сработало .. однако теперь я получаю p.waitFor (), выбрасывающий InterruptedException со значением 2, есть идеи? - person DFSOKO; 11.10.2011

Ваша проблема связана с контекстом, в котором запускается ваш сервлет. Вам нужно получить контекст, а затем перейти к своему файлу. См. Здесь, чтобы узнать, как получить контекст сервлета: Как получить контекст сервлета из ServletRequest в Servlet 2.5?

Вы достигнете своего контекста сервлета следующим образом:

ServletContext context = config.getServletContext();

Тогда просто используйте этот контекст так:

String cmdArr = new String[]{"perl", context.getRealPath("/") + "WEB-INF/cgi/test.pl"};
person user2597843    schedule 27.06.2014