简体   繁体   中英

Java code unable to use temporary file created (No output response from the process that executed the shell script)

I am writing a Java code that will create and write a shell command into temporary file which will be then used to run using 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");
    }

I am getting error that tempcmdline.sh is not found. I tried adding /tmp/tempcmdline thinking default temporary directory used by createTempFile will be /tmp on UNIX.

Please share any working code where we can specify a directory and use it in process.

[EDIT] I tried getting absolutepath using file.getAbsolutePath() and pass full path name in process. However this is giving empty response (when I read the process output with InputStreamReader) while when I run the shell script manually on Unix it gives me a proper 1 line o/p message.

[EDIT] I figured out that temporary file getting created has \\r which is causing the issue.

[UPDATE] Following is the updated code that worked for me:

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

Error details and learnings to share:

1) Initial issue was that response from process was leading to no InputStream. To debug I used IOUtils.copy(p.getInputStream(), System.out); Then, actual error showed up from process stating no such file found (tempcmdline.sh)

2) Upon understanding that a temporary file name will be different, I got the absolute path and passed it to the process. Next error was no response as though shell script was empty. Loop above in initial code did not handle newline and was incorrect. New code added has the fix.

Next error was invalid characters "\\r" which was due to shell script file created on Windows. I simply cleaned it on Eclipse editor and it was fine.

3) After debugging I removed IOUtils.copy step as I wanted the output to be read through Inputstream.

Hope it helps someone..

It appears that you are attempting to write to a temp file, named something like "/tmp/tempcmdline234765876.sh", and then you are attempting to run "tempcmdline.sh".

Add a System.out.println(file); to see what the actual temp filename is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM