Проблема ProcessBuilder, выполняющий скрипт sh - PullRequest
1 голос
/ 19 ноября 2010

пытается выполнить скрипт, используя этот фрагмент кода:

String command = "./myScript.sh";
pb = new ProcessBuilder(command, param1, param2);
pb.directory(directory);
pb.start();

Я не получаю никаких ошибок, но и предполагаемых результатов.Во всяком случае, я попытался запустить ту же команду, direclty в терминале, и все работает правильно.
Я что-то упустил ??

Заранее спасибо

Ответы [ 2 ]

4 голосов
/ 20 ноября 2010

Когда вы запускаете процесс (pb.start()), вы получаете экземпляр Process.Если ваш скрипт читает ввод или записывает вывод в stdout или stderr, вам нужно обрабатывать это в отдельных потоках, используя Process.getInputStream(), ...getOutputStream() и getErrorStream().Если вы этого не сделаете, процесс может зависнуть.Вы также должны позвонить Process.waitFor(), а затем Process.exitValue(), чтобы получить статус возврата процесса.Если это отрицательное число, то система не смогла запустить ваш скрипт.

РЕДАКТИРОВАТЬ: Вот короткий упрощенный пример.Это только игрушка и будет надежно работать ТОЛЬКО при следующих условиях:

  1. Скрипт не требует ввода

  2. Скрипт непроизводить большое количество вывода как на stdout, так и на stderr.Если это так, то, поскольку программа считывает весь stdout перед stderr, буфер stderr может заполниться и заблокировать завершение процесса.В «реальной» реализации вы бы читали stdout и stderr в отдельных потоках (подсказка, оберните метод loadStream() в классе, который реализует Runnable).

public class PBTest
{
    public static void main(String[] args) throws Exception
    {
        ProcessBuilder pb = new ProcessBuilder("sc","query","wuauserv");
        Process p = pb.start();
        String output = loadStream(p.getInputStream());
        String error  = loadStream(p.getErrorStream());
        int rc = p.waitFor();
        System.out.println("Process ended with rc=" + rc);
        System.out.println("\nStandard Output:\n");
        System.out.println(output);
        System.out.println("\nStandard Error:\n");
        System.out.println(error);
    }

    private static String loadStream(InputStream s) throws Exception
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(s));
        StringBuilder sb = new StringBuilder();
        String line;
        while((line=br.readLine()) != null)
            sb.append(line).append("\n");
        return sb.toString();
    }
}
2 голосов
/ 23 ноября 2010

Проблема была не в том, как я назвал сценарий, и это было правильно.
Но это было внутри сценария.Сначала это было:

#!/bin/bash
inputFolder=$1
outputFolder=$2 

cd $inputFolder

for file in `ls ` ; do
ffmpeg -i $inputFolder/$file -ar 22050 $outputFolder/$file.mp4 
done

Но я получил ffmpeg command not found, поэтому я изменил его на:

#!/bin/bash
inputFolder=$1
outputFolder=$2 

cd $inputFolder

for file in `ls ` ; do
/usr/local/bin/ffmpeg -i $inputFolder/$file -ar 22050 $outputFolder/$file.mp4 
done  

с траекторией отверстия.Но я до сих пор сомневаюсь, зачем это нужно, если у меня есть ffmpeg в моем пути и я выполняю в консоли директорию любого каталога ??Если кто-то может дать мне ответ, это будет приветствоваться:)

...