Java-код не может использовать созданный временный файл (нет выходного ответа от процесса, который выполнил сценарий оболочки) - PullRequest
0 голосов
/ 19 марта 2019

Я пишу код Java, который создаст и запишет команду оболочки во временный файл, который затем будет использоваться для запуска с использованием компоновщика процессов.

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.

Пожалуйста, поделитесь любым рабочим кодом, где мы можем указать каталог и использовать его в процессе.

[РЕДАКТИРОВАТЬ] Я попытался получить absolutepath с помощью file.getAbsolutePath () и передать полный путь в процессе.Однако это дает пустой ответ (когда я читаю выходные данные процесса с InputStreamReader), в то время как когда я запускаю сценарий оболочки вручную в Unix, он дает мне правильное однострочное сообщение o / p.

[EDIT] Я понялэтот временный созданный файл имеет \ 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();
        }     

Подробности ошибок и сведения, которыми можно поделиться:

1) Первоначальная проблема заключалась в том, что ответ процесса не приводил к отсутствию InputStream.Для отладки я использовал IOUtils.copy (p.getInputStream (), System.out);Затем из процесса обнаружилась фактическая ошибка, сообщающая, что такой файл не найден (tempcmdline.sh)

2) Поняв, что имя временного файла будет другим, я получил абсолютный путь и передал его процессу.Следующая ошибка не была получена, как будто сценарий оболочки пустЦикл выше в исходном коде не обрабатывал символ новой строки и был некорректным.В новом добавленном коде есть исправление.

Следующая ошибка: недопустимые символы "\ r" из-за файла сценария оболочки, созданного в Windows.Я просто очистил его в редакторе Eclipse, и все было в порядке.

3) После отладки я удалил шаг IOUtils.copy, поскольку хотел, чтобы вывод читался через Inputstream.

Надеюсь, это кому-нибудь поможет..

1 Ответ

1 голос
/ 19 марта 2019

Похоже, что вы пытаетесь записать во временный файл с именем типа "/tmp/tempcmdline234765876.sh", а затем пытаетесь запустить "tempcmdline.sh".

Добавить систему.out.println (файл);чтобы увидеть, каково реальное временное имя файла.

...