SoFunction
Updated on 2025-03-08

Implementation of Java execution shell commands

Preface

There are many ways to execute shell commands in Java, but during the application process, we may encounter some special situations that lead to the execution of the script failing and not taking effect.

1. Case

Scene

Java service, automatically restart the service if needed. Then we execute shell commands through Java and use the commonly used jdk method: ().exec(command) method to restart the service, which may cause the restart to fail.

reason

  • Java executes local commands to start a child process. By default, the child process and the parent process I/O are connected through a pipeline ()
  • When the service executes its own restart command, the parent process is closed and the pipeline connection is interrupted, which will cause the child process to crash and the subsequent startup cannot be completed.

Solution

  • Setting the I/O source or destination of the child process will be the same as the current process, and the two are independent of each other.
  • Set the subprocess IO output redirect to the specified file

Here we adopt the first solution

ProcessBuilder pb = new ProcessBuilder("service","java-service","restart");
();
();
();
();

ProcessBuilder is also a class that has been found in J2SE1.5. This class is used to create operating system processes, which provides a way to start and manage processes (that is, applications). Before J2SE 1.5, the process control and management were implemented by the Process class.

static     DISCARD    
Indicates that the child process output will be discarded。
static     INHERIT    
Indicates child processI / OThe source or destination will be the same as the current process。
static     PIPE    
Indicates child processI / OWill be connected to the currentJavaprocess。

ProcessBuilder can configure the child process I/O source or destination that executes the script will be the same as the current process. After binding, performing a restart will succeed and the pipeline will not be disconnected.

ProcessBuilder can be used for reference connection:

ProcessBuilder api
ProcessBuilder Chinese Documentation

2. Expand

Create a temporary script and execute shell commands

<dependency>
   <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

You can copy and use it directly, please note that you can introduce the maven package

public static String runAndResult(String cmd){
        StringBuilder sb = new StringBuilder();
        BufferedReader br = null;
        boolean execFlag = true;
        String uuid = ().toString().replace("-","");
        String tempFileName = "./temp" + uuid +".sh";
        try {
            String osName = ("").toUpperCase();
            if (("^(?i)LINUX.*$") || ("MAC")) {
                FileWriter execute_fw = new FileWriter(tempFileName);
                BufferedWriter execute_bw=new BufferedWriter(execute_fw);
                execute_bw.write(cmd + "\n");
                execute_bw.close();
                execute_fw.close();
                String command ="bash " + tempFileName;
                Process p = ().exec(command);
                ();
                br = new BufferedReader(new InputStreamReader(()));
                String line;
                while ((line = ()) != null) {
                    (());
                    (line);
                }
                ();
                br = new BufferedReader(new InputStreamReader(()));
                while ((line = ()) != null) {
                    (());
                    (line);
                    if (() &gt; 0){
                        execFlag = false;
                    }
                }
                ();
                if (execFlag){
                }else {
                    throw new RuntimeException(());
                }
            }else {
                throw new RuntimeException("Unsupported operating system types");
            }
        } catch (Exception e) {
            ("Execution failed",e);
        }finally {
            if (br != null){
                try {
                    ();
                } catch (IOException e) {
                    ("io exception",e);
                }
            }
            (new File(tempFileName));
        }
        return ();
    }

3. Summary

Practice is the only criterion for testing truth, and you must summarize and record more in your work and life. If you find it useful, please like it. It's also good to bookmark it.

This is the end of this article about the implementation of Java shell command execution. For more related Java shell execution content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!