问题ProcessBuilder运行脚本sh

时间:2010-11-19 13:59:34

标签: java processbuilder

尝试使用这段代码执行脚本:

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

我没有得到任何错误,但没有得到假设的结果。无论如何,我试着在终端中运行相同的命令,直接,并且一切正常 我错过了什么吗?

提前致谢

2 个答案:

答案 0 :(得分:4)

当您启动流程(pb.start())时,您将返回Process个实例。如果您的脚本读取输入或将输出写入stdout或stderr,则需要使用Process.getInputStream()...getOutputStream()getErrorStream()在单独的线程上处理此操作。如果您不这样做,该过程可能会挂起。您还应该调用Process.waitFor()然后调用Process.exitValue()以获取进程的返回状态。如果它是负数,则系统无法启动您的脚本。

编辑:这是一个简短的例子。这只是一个玩具,只有在以下条件下才能可靠地工作:

  1. 该脚本不需要任何输入

  2. 脚本在stdout和stderr上都不会产生大量输出。如果是,那么由于程序在stderr之前读取所有stdout,stderr缓冲区可能会填满并阻止进程完成。在“真实”实现中,您将在单独的线程中读取stdout和stderr(提示,将loadStream()方法包装在实现Runnable的类中。)

  3. 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();
        }
    }
    

答案 1 :(得分:2)

问题不在于我调用脚本的方式,这是正确的 但它在剧本里面。起初它是:

#!/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并且我在控制台直接执行任何目录? 如果有人能给我一个答案,那将是受欢迎的:)