Переменная среды ProcessBuilder в java

Я пытаюсь добавить переменную среды для объекта ProcessBuilder, но затем, когда я вызываю эту новую переменную в ProcessBuilder, я получаю сообщение об ошибке. вот как я строю процесс

public class OTU
{
    public static void main(String[] args) throws Exception
    {
        ProcessBuilder pb = new ProcessBuilder();
        Map<String, String> env = pb.environment();
        //set environment variable u
        env.put("u", "util/");

        pb.command("echo $u");
        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();
    }
}

я получаю ошибку

Exception in thread "main" java.io.IOException: Cannot run program "$u": java.io.IOException: error=2, No such file or directory
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:475)
    at ca.utoronto.siseq_1_2.OTU.main(OTU.java:22)
Caused by: java.io.IOException: java.io.IOException: error=2, No such file or directory
    at java.lang.UNIXProcess.<init>(UNIXProcess.java:164)
    at java.lang.ProcessImpl.start(ProcessImpl.java:81)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:468)
    ... 1 more

Я не понимаю, почему я получаю сообщение об ошибке, если я просто установил переменную для этого процесса. Пожалуйста, помогите мне, как установить переменную env, чтобы я мог использовать ее в ProcessBuilder.


person Julio Diaz    schedule 25.06.2012    source источник


Ответы (2)


Пример Альфредо О дает вам правильное представление. Вам нужно указать ProcessBuilder, какую программу использовать для выполнения вашей команды. В этом случае bash с ключом "-c", который указывает bash интерпретировать то, что будет дальше (например, "echo $u") в качестве команды.

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Map;

public class OTU {
    public static void main(String[] args) throws Exception {
        ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", "echo $u");
        Map<String, String> env = pb.environment();
        // set environment variable u
        env.put("u", "util/");

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

Это дает следующий результат:

Process ended with rc=0

Standard Output:

util/


Standard Error:
person orangepips    schedule 26.06.2012
comment
префикс для платформы windows: cmd /c ... префикс для платформы unix: sh -c ... - person Donatello; 17.02.2017

Это работает для меня в Windows:

@Test
public void testProcessBuilder() throws IOException {
    ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/C", "echo Hello %name%");
    Map<String, String> environment = processBuilder.environment();
    environment.put("name", "Alfredo Osorio");
    Process p = processBuilder.start();
    String line;
    BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
    while ((line = r.readLine()) != null) {
        System.out.println(line);
    }
    r.close();
}

Вывод:

Привет Альфредо Осорио

Как видите, в Windows вы используете %environmentVariable% вместо $environementVariable.

person Alfredo Osorio    schedule 25.06.2012
comment
Есть ли способ сделать этот cross os? - person Julio Diaz; 26.06.2012
comment
+1 за то, что указал ему правильное направление, хотя и не объяснил, почему это работает - вы сказали Java выполнить cmd.exe. - person orangepips; 26.06.2012