如何从Java代码运行Unix shell脚本?

150 java unix shell

从Java运行Unix命令非常简单.

Runtime.getRuntime().exec(myCommand);
Run Code Online (Sandbox Code Playgroud)

但是可以从Java代码运行Unix shell脚本吗?如果是,从Java代码中运行shell脚本是一个好习惯吗?

Mil*_*ous 173

您应该真正关注Process Builder.它真的是为这种东西而建的.

ProcessBuilder pb = new ProcessBuilder("myshellScript.sh", "myArg1", "myArg2");
 Map<String, String> env = pb.environment();
 env.put("VAR1", "myValue");
 env.remove("OTHERVAR");
 env.put("VAR2", env.get("VAR1") + "suffix");
 pb.directory(new File("myDir"));
 Process p = pb.start();
Run Code Online (Sandbox Code Playgroud)

  • 从JAVA调用脚本是一种好习惯吗?任何性能问题? (3认同)

Jac*_*eow 23

我想说从Java运行shell脚本不符合Java的精神.Java意味着是跨平台的,运行shell脚本会将其使用限制在UNIX.

话虽如此,绝对可以从Java中运行shell脚本.您使用的是与您列出的完全相同的语法(我自己没有尝试过,但是尝试直接执行shell脚本,如果不起作用,请执行shell本身,将脚本作为命令行参数传递) .

  • 是的,但在许多方面,"Java的精神"或"一次到处运行"的口头禅是一个神话无论如何. (43认同)
  • 它有什么神话般的神话? (15认同)
  • 关于它的神话是什么,你通常最终会写出大量的`switch`和`if`语句,以解决在不同平台上不能完全相同的所有细微差别,尽管那些想出的人做出了最大努力java核心库. (15认同)
  • @BobbyShaftoe我已经写了16年java,并且总是在windows上开发,我的所有应用程序总是部署在solaris/ibm或oracle风格的unix盒子上,所以我不知道你在说什么 (10认同)
  • 令人惊讶的是!我同意上面的所有评论和答案! (2认同)
  • @KalpeshSoni就是这个原因; 你总是有一个固定的目标部署平台; 如果必须同时部署到Windows,Linux,Mac和Solaris,则情况会有所不同. (2认同)

Chr*_*nce 21

我想你已回答了自己的问题

Runtime.getRuntime().exec(myShellScript);
Run Code Online (Sandbox Code Playgroud)

至于它是否是一个好习惯......你想用一个你不能用Java做的shell脚本做什么?


Not*_*bug 21

您也可以使用Apache Commons exec库.

示例:

package testShellScript;

import java.io.IOException;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;

public class TestScript {
    int iExitValue;
    String sCommandString;

    public void runScript(String command){
        sCommandString = command;
        CommandLine oCmdLine = CommandLine.parse(sCommandString);
        DefaultExecutor oDefaultExecutor = new DefaultExecutor();
        oDefaultExecutor.setExitValue(0);
        try {
            iExitValue = oDefaultExecutor.execute(oCmdLine);
        } catch (ExecuteException e) {
            System.err.println("Execution failed.");
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println("permission denied.");
            e.printStackTrace();
        }
    }

    public static void main(String args[]){
        TestScript testScript = new TestScript();
        testScript.runScript("sh /root/Desktop/testScript.sh");
    }
}
Run Code Online (Sandbox Code Playgroud)

为了进一步参考,还给出了Apache Doc的一个例子.

  • 最好的解决方案。 (2认同)

Des*_*gos 11

是的,有可能这样做.这对我有用.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import org.omg.CORBA.portable.InputStream;

public static void readBashScript() {
        try {
            Process proc = Runtime.getRuntime().exec("/home/destino/workspace/JavaProject/listing.sh /"); //Whatever you want to execute
            BufferedReader read = new BufferedReader(new InputStreamReader(
                    proc.getInputStream()));
            try {
                proc.waitFor();
            } catch (InterruptedException e) {
                System.out.println(e.getMessage());
            }
            while (read.ready()) {
                System.out.println(read.readLine());
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
Run Code Online (Sandbox Code Playgroud)


小智 8

这是我的例子。希望这是有道理的。

public static void excuteCommand(String filePath) throws IOException{
    File file = new File(filePath);
    if(!file.isFile()){
        throw new IllegalArgumentException("The file " + filePath + " does not exist");
    }
    if(isLinux()){
        Runtime.getRuntime().exec(new String[] {"/bin/sh", "-c", filePath}, null);
    }else if(isWindows()){
        Runtime.getRuntime().exec("cmd /c start " + filePath);
    }
}
public static boolean isLinux(){
    String os = System.getProperty("os.name");  
    return os.toLowerCase().indexOf("linux") >= 0;
}

public static boolean isWindows(){
    String os = System.getProperty("os.name");
    return os.toLowerCase().indexOf("windows") >= 0;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

是的,这是可能的,您已经回答了!关于良好的实践,我认为最好从文件而不是直接从代码中启动命令。因此,您必须让 Java 执行现有.bat, .sh, .ksh... 文件中的命令列表(或一个命令)。这是在文件中执行命令列表的示例MyFile.sh

    String[] cmd = { "sh", "MyFile.sh", "\pathOfTheFile"};
    Runtime.getRuntime().exec(cmd);
Run Code Online (Sandbox Code Playgroud)


ana*_*ocs 5

为了避免硬编码绝对路径,您可以使用以下方法来查找并执行脚本(如果脚本位于根目录中)。

public static void runScript() throws IOException, InterruptedException {
    ProcessBuilder processBuilder = new ProcessBuilder("./nameOfScript.sh");
    //Sets the source and destination for subprocess standard I/O to be the same as those of the current Java process.
    processBuilder.inheritIO();
    Process process = processBuilder.start();

    int exitValue = process.waitFor();
    if (exitValue != 0) {
        // check for errors
        new BufferedInputStream(process.getErrorStream());
        throw new RuntimeException("execution of script failed!");
    }
}
Run Code Online (Sandbox Code Playgroud)