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

Java代码无法使用创建的临时文件(执行shell脚本的进程没有输出响应),java,processbuilder,Java,Processbuilder,我正在编写一个Java代码,该代码将创建一个shell命令并将其写入临时文件,然后使用process builder运行该文件 File file = null; InputStream input = getClass().getResourceAsStream("/somecommand.sh"); try { file = File.createTempFile("tempcmdline", ".sh"); } catch (IOExceptio

我正在编写一个Java代码,该代码将创建一个shell命令并将其写入临时文件,然后使用process builder运行该文件

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");
    }
File文件=null;
InputStream输入=getClass().getResourceAsStream(“/somecommand.sh”);
试一试{
file=file.createTempFile(“tempcmdline”,“.sh”);
}捕获(IOE1异常){
e1.printStackTrace();
}
输出流输出;
试一试{
out=新文件输出流(文件);
BufferedReader reader=新的BufferedReader(新的InputStreamReader(输入));
BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(out));
弦线;
而((line=reader.readLine())!=null){
作者:写(行);
}
}捕获(IOE1异常){
e1.printStackTrace();
}
过程p;
试一试{
List cmdList=new ArrayList();
添加(“/usr/bin/bash”);
添加(“tempcmdline.sh”);
ProcessBuilder pb=新的ProcessBuilder(cmdList);
pb.重定向错误流(真);
p=pb.start();
复制(p.getInputStream(),System.out);
p、 waitFor();
BufferedReader=新的BufferedReader(新的InputStreamReader(p.getInputStream());
弦线;
如果((line=reader.readLine())!=null){
System.out.println(“某些显示”+行);
}否则{
System.out.println(“其他一些显示”);
}
找不到tempcmdline.sh时出错。我尝试添加/tmp/tempcmdline,认为在UNIX上createTempFile使用的默认临时目录将是/tmp

请共享我们可以指定目录并在过程中使用的任何工作代码

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

[编辑]我发现正在创建的临时文件\r导致了问题

[更新]以下是适用于我的更新代码:

            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();
        }     
File文件=null;
InputStream输入=getClass().getResourceAsStream(“/someCommand.sh”);
试一试{
file=file.createTempFile(“tempcmdline”,“.sh”);
字符串tempShell=file.getAbsolutePath();
文件.copy(输入,路径.get(tempShell),替换现有文件);
file.deleteOnExit();//用于测试的注释,以查看它是如何编写的
}捕获(IOE1异常){
e1.printStackTrace();
}
过程p;
试一试{
字符串tempShellFile=file.getAbsolutePath();
List cmdList=new ArrayList();
cmdList.添加(“sh”);
添加(tempShellFile);
cmdList.add(应用程序名称);
添加(serviceAccount);
ProcessBuilder pb=新的ProcessBuilder(cmdList);
//pb.重定向错误流(真);
p=pb.start();
//IOUtils.copy(p.getInputStream(),System.out);//取消对测试的注释
p、 waitFor();
BufferedReader=新的BufferedReader(新的InputStreamReader(p.getInputStream());
弦线;
如果((line=reader.readLine())!=null){
System.out.println(“某些消息”);
}否则{
System.out.println(“其他消息”);
}
}捕获(IOE异常){
e、 printStackTrace();
}捕捉(中断异常e){
e、 printStackTrace();
}     
要共享的错误详细信息和学习:

1) 最初的问题是来自进程的响应导致并没有InputStream; 然后,实际的错误出现在进程中,说明找不到这样的文件(tempcmdline.sh)

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

下一个错误是无效字符“\r”,这是由于在Windows上创建的shell脚本文件造成的。我只是在Eclipse编辑器上清理了它,结果很好

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


希望对某人有所帮助。

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


添加System.out.println(文件);以查看实际的临时文件名。

我尝试使用file.getAbsolutepath()并将其传递给porcessbuilder,但返回值为null。什么是null?文件、getAbsolutepath或pb.start()?请在此帮助我。shell脚本输出为空响应。我已修复该问题,其工作正常。请参阅我的编辑。“无法使用”不是问题描述。您尚未提供实际的异常或错误消息。您尚未关闭输出文件。您正在丢失行终止符。您正在等待进程退出在您读取任何可能导致死锁的输出之前。您应该将其输出读取到流的末尾,然后等待。@user207421谢谢。我已经解决了这个问题。我将通过此练习编辑更新的代码和我的学习。您能检查更新的代码并共享您的输入吗?特别是关于死锁的输入。