Executar script Shell no Java

Estou desenvolvendo um programa que chame um script shell e o execute, mas não recebo feedback algum, nem de erro. O .sh em questão abriria o Firefox pelo Gnome Terminal (1).

import java.io.IOException;

public class UpdateUbuntu {
    public void UpdateSystem() {

        // -- Linux --
        String[] cmd = new String[]{"/bin/sh", "-c",
                "gnome-terminal --execute ./FF.sh"};

        ProcessBuilder processBuilder = new ProcessBuilder(cmd);

        try {
            Process process = processBuilder.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Tentei também chamar de forma direta, mas nem um resultado positivo (2). Alguma sugestão?

import java.io.IOException;

public class UpdateUbuntu {
    public void UpdateSystem() {

        // -- Linux --
        // String[] cmd = new String[]{"/home/joogabriel/.UpdateAll.sh"};
        String[] cmd = new String[]{"/home/joogabriel/FF.sh"};

        ProcessBuilder processBuilder = new ProcessBuilder(cmd);

        try {
            Process process = processBuilder.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

OBS: já tornei o .sh executável com chmod + x

processBuilder assim como a maioria das bibliotecas nas linguagens por aí voltadas a rodar subprocessos, não tem como te dizer muito mais via exceções nativas além de se conseguiu ou não criar o processo e se o programa terminou, com ou sem sucesso.

Todos os processos no Linux tem 3 descritores de arquivos padrões que respondem pela entrada (stdin), saída padrão(stdout) e saída de erro(stderr). É nos últimos 2 que você precisa buscar feedback:

Process.getInputStream()
Process.getErrorStream()

Um simples exemplo, à complementar a resposta do @romulopb, onde executará o utilitário ping, lendo o status de saída, e guarda em buffer.

import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.stream.Collectors;


public class shell {
    public static void main(String[] args) {
        String[] cmd = new String[]{"ping", "-c4", "google.com"};

        ProcessBuilder processBuilder = new ProcessBuilder(cmd);

        try {
            Process process = processBuilder.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

            System.out.println(reader.lines().collect(Collectors.joining(System.lineSeparator())));

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

1 curtida

Apenas lembrando que o subprocesso precisa terminar, caso contrário você vai precisar de um pouco mais de trabalho usando threads ou outras soluções assíncronas caso você queira tratar a saída do subprocesso enquanto ele está executando.

1 curtida