Java代码无法使用创建的临时文件(执行Shell脚本的进程没有输出响应)

时间:2019-03-19 17:29:35

标签: java processbuilder

我正在编写一个Java代码,该代码将创建一个Shell命令并将其写入临时文件,然后将其用于使用进程生成器运行。

File file = null;
    InputStream input = getClass().getResourceAsStream("/somecommand.sh");


    try {
        file = File.createTempFile("tempcmdline", ".sh");
    } catch (IOException e1) {

        e1.printStackTrace();
    }
    OutputStream out;
    try {
        out = new FileOutputStream(file);
        BufferedReader reader=new BufferedReader(new InputStreamReader(input)); 
        BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(out));

         String line; 
            while((line = reader.readLine()) != null) { 

                writer.write(line);

            }

    } catch (IOException e1) {

        e1.printStackTrace();
    }



    Process p;
    try {
    List<String> cmdList = new ArrayList<String>();

    cmdList.add("/usr/bin/bash");
    cmdList.add("tempcmdline.sh");


    ProcessBuilder pb = new ProcessBuilder(cmdList);
    pb.redirectErrorStream(true);
    p = pb.start();
    IOUtils.copy(p.getInputStream(), System.out);

    p.waitFor(); 

    BufferedReader reader=new BufferedReader(new InputStreamReader(p.getInputStream())); 

    String line; 
    if((line = reader.readLine()) != null) { 
        System.out.println("some display" + line);
    } else {
        System.out.println("some other display");
    }

我遇到找不到tempcmdline.sh的错误。我尝试添加/ tmp / tempcmdline,以为createTempFile使用的默认临时目录在UNIX上为/ tmp。

请分享所有可以在其中指定目录并在使用中的工作代码。

[编辑]我尝试使用file.getAbsolutePath()获取绝对路径,并在处理过程中传递完整路径名。但是,这给出了空的响应(当我使用InputStreamReader读取进程输出时),而当我在Unix上手动运行shell脚本时,它会给我正确的1行o / p消息。

[编辑]我发现正在创建的临时文件包含\ r,这引起了问题。

[UPDATE]以下是对我有用的更新代码:

            File file = null;
        InputStream input = getClass().getResourceAsStream("/someCommand.sh");

        try {
            file = File.createTempFile("tempcmdline", ".sh");
            String tempShell = file.getAbsolutePath();
                Files.copy(input, Paths.get(tempShell), REPLACE_EXISTING);
            file.deleteOnExit();  //comment for testing to see how it is written
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        Process p;
        try {
        String tempShellFile = file.getAbsolutePath();
        List<String> cmdList = new ArrayList<String>();

        cmdList.add("sh");
            cmdList.add(tempShellFile);
            cmdList.add(applicationName);
            cmdList.add(serviceAccount);

        ProcessBuilder pb = new ProcessBuilder(cmdList);
        //pb.redirectErrorStream(true); 
        p = pb.start();
        //IOUtils.copy(p.getInputStream(), System.out); //uncomment for testing

        p.waitFor(); 
        BufferedReader reader=new BufferedReader(new InputStreamReader(p.getInputStream())); 

        String line; 
        if((line = reader.readLine()) != null) { 
            System.out.println("some message");
        } else {
            System.out.println("some other message");
        }

        }catch (IOException e) {
            e.printStackTrace();
        }catch (InterruptedException e) {
            e.printStackTrace();
        }     

错误详细信息和分享的经验教训:

1)最初的问题是来自流程的响应导致没有InputStream。为了调试,我使用了IOUtils.copy(p.getInputStream(),System.out); 然后,从过程中显示出实际错误,指出找不到此类文件(tempcmdline.sh)

2)在了解到临时文件名会有所不同之后,我得到了绝对路径并将其传递给进程。 下一个错误是没有响应,好像shell脚本为空。初始代码中的上述循环无法处理换行符,并且是错误的。添加的新代码已修复。

下一个错误是无效字符“ \ r”,这是由于Windows上创建的外壳脚本文件引起的。我只是在Eclipse编辑器上对其进行了清理,就可以了。

3)调试后,我删除了IOUtils.copy步骤,因为我希望通过Inputstream读取输出。

希望它可以帮助某人。

1 个答案:

答案 0 :(得分:1)

您似乎正在尝试写入一个名为“ /tmp/tempcmdline234765876.sh”的临时文件,然后尝试运行“ tempcmdline.sh”。

添加一个System.out.println(file);看看实际的临时文件名是什么。