Java shell to execute / coordinate processes?

I know about using Runtime.exec , you pass it your own program to run + arguments. If this is a regular program, you can run it directly. If it is a shell script, you need to run an external shell program like shor cshor cmd.exe.

Is there any Java class (standard or open) that implements a shell, i.e. a program in which you pass a command line or script to that executes commands and accordingly redirects standard I / O / err, so that you could to convey the type of line foo | bar > baz.outin, and it will run the program fooand barwithout having to launch another executable file is Java?

(And by the shell, I do not mean BeanShell or the standalone Rhino Javascript interpreter, it is a Java implementation for executing Java and Javascript code. I am talking about Java implementations for executing non-Java executable files and handle I / O redirection plumbing.)

+3
source share
4 answers

Ok, I worked:

Basically, you need to call bash with "-s", and then write the full command line to it.

public class ShellExecutor {

  private String stdinFlag;
  private String shell;

  public ShellExecutor(String shell, String stdinFlag) 
  {
    this.shell = shell;
    this.stdinFlag = stdinFlag;
  }

  public String execute(String cmdLine) throws IOException 
  {
    StringBuilder sb = new StringBuilder();
    Runtime run = Runtime.getRuntime();
    System.out.println(shell);
    Process pr = run.exec(cmdLine);
    BufferedWriter bufWr = new BufferedWriter(
        new OutputStreamWriter(pr.getOutputStream()));
    bufWr.write(cmdLine);
    try 
    {
      pr.waitFor();
} catch (InterruptedException e) {}
    BufferedReader buf = new BufferedReader(
        new InputStreamReader(pr.getInputStream()));
    String line = "";
    while ((line = buf.readLine()) != null) 
    {
        sb.append(line + "\n");
    }
    return sb.toString();
  }
}

Then use it as follows:

ShellExecutor excutor = new ShellExecutor("/bin/bash", "-s");
try {
  System.out.println(excutor.execute("ls / | sort -r"));
} catch (IOException e) {
  e.printStackTrace();
}

Obviously you have to do something wrong, but this is a working example.

+3
source

Since JDK 1.5 is java.lang.ProcessBuilder, which also handles std and err threads. This is a kind of replacement for java.lang.Runtime

+2

Runtime.exec

.

String cmd = "ls -al";
    Runtime run = Runtime.getRuntime();
    Process pr = run.exec(cmd);
    pr.waitFor();
    BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream()));
    String line = "";
    while ((line=buf.readLine())!=null) {
        System.out.println(line);
    }

, , pipe redirect, , . , . bash Java -c "ls | sort", . , .

+2

API ProcessBuilder, java.

Runtime.getRuntime().exec(...) , . exec() , exec(), . ProcessBuilder, , varargs , . , .

ProcessBuilder Runtime.exec()

.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.List;

public class ProcessBuilderTest {
    static ProcessBuilder processBuilder = null;
    static Process spawnProcess = null;
    static int exitValue;
    static int pid;
    static List<String> commands;

    public static void main(String[] args) {
        runSqoop();
    }

    public static void runSqoop() {
        String[] commands = { "ssh", "node", "commands" };
        processBuilder = new ProcessBuilder(commands);
        try {
            System.out.println("Executing " + commands.toString());
            spawnProcess = processBuilder.inheritIO().start();
            try {
                exitValue = spawnProcess.waitFor();
                pid = getPID(spawnProcess);
                System.out.println("The PID is " + pid);
            } catch (InterruptedException e) {
                System.out.println(e.getMessage());
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
            System.out.println("Process exited with the status :" + exitValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static int getPID(Process process) {
        try {
            Class<?> processImplClass = process.getClass();
            Field fpid = processImplClass.getDeclaredField("pid");
            if (!fpid.isAccessible()) {
                fpid.setAccessible(true);
            }
            return fpid.getInt(process);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return -1;
        }
    }

}
+1

Source: https://habr.com/ru/post/1720590/


All Articles