mic*_*zer 19 java bash runtime.exec
我有以下课程.它允许我通过java执行命令.
public class ExecuteShellCommand {
public String executeCommand(String command) {
    StringBuffer output = new StringBuffer();
    Process p;
    try {
        p = Runtime.getRuntime().exec(command);
        p.waitFor();
        BufferedReader reader = 
                        new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line = "";           
        while ((line = reader.readLine())!= null) {
            output.append(line + "\n");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return output.toString();
}
}
当我运行命令时,不保存上一个命令的结果.例如:
public static void main(String args[]) {
    ExecuteShellCommand com = new ExecuteShellCommand();
    System.out.println(com.executeCommand("ls"));
    System.out.println(com.executeCommand("cd bin"));
    System.out.println(com.executeCommand("ls"));
}
给出输出:
bin
src
bin
src
为什么第二个'ls'命令没有显示'bin'目录的内容?
Ren*_*ink 17
你开始一个新的过程Runtime.exec(command).每个进程都有一个工作目录.这通常是启动父进程的目录,但您可以更改进程启动的目录.
我建议使用ProcessBuilder
ProcessBuilder pb = new ProcessBuilder("ls");
pb.inheritIO();
pb.directory(new File("bin"));
pb.start();
如果要在shell中运行多个命令,最好创建一个临时shell脚本并运行它.
public void executeCommands() throws IOException {
    File tempScript = createTempScript();
    try {
        ProcessBuilder pb = new ProcessBuilder("bash", tempScript.toString());
        pb.inheritIO();
        Process process = pb.start();
        process.waitFor();
    } finally {
        tempScript.delete();
    }
}
public File createTempScript() throws IOException {
    File tempScript = File.createTempFile("script", null);
    Writer streamWriter = new OutputStreamWriter(new FileOutputStream(
            tempScript));
    PrintWriter printWriter = new PrintWriter(streamWriter);
    printWriter.println("#!/bin/bash");
    printWriter.println("cd bin");
    printWriter.println("ls");
    printWriter.close();
    return tempScript;
}
当然,您也可以在系统上使用任何其他脚本.在运行时生成脚本有时会有意义,例如,如果执行的命令必须更改.但是您应该首先尝试创建一个可以使用参数调用的脚本,而不是在运行时动态生成它.
如果脚本生成很复杂,使用像velocity这样的模板引擎也可能是合理的.
您可以形成一个复杂的 bash 命令来执行所有操作:“ls; cd bin; ls”。要完成这项工作,您需要显式调用 bash。这种方法应该为您提供 bash 命令行的所有功能(引号处理、$ 扩展、管道等)。
/**
 * Execute a bash command. We can handle complex bash commands including
 * multiple executions (; | && ||), quotes, expansions ($), escapes (\), e.g.:
 *     "cd /abc/def; mv ghi 'older ghi '$(whoami)"
 * @param command
 * @return true if bash got started, but your command may have failed.
 */
public static boolean executeBashCommand(String command) {
    boolean success = false;
    System.out.println("Executing BASH command:\n   " + command);
    Runtime r = Runtime.getRuntime();
    // Use bash -c so we can handle things like multi commands separated by ; and
    // things like quotes, $, |, and \. My tests show that command comes as
    // one argument to bash, so we do not need to quote it to make it one thing.
    // Also, exec may object if it does not have an executable file as the first thing,
    // so having bash here makes it happy provided bash is installed and in path.
    String[] commands = {"bash", "-c", command};
    try {
        Process p = r.exec(commands);
        p.waitFor();
        BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line = "";
        while ((line = b.readLine()) != null) {
            System.out.println(line);
        }
        b.close();
        success = true;
    } catch (Exception e) {
        System.err.println("Failed to execute bash with command: " + command);
        e.printStackTrace();
    }
    return success;
}
每个调用都在其自己的 shell 中执行。因此,第三次调用看不到第二次调用的“cd”。
请参阅: https: //docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#exec(java.lang.String)。
这表明该命令在单独的进程中运行。这样你就产生了 3 个进程。
如果您希望所有 3 个进程都在同一个进程中,请尝试以下操作:
com.executeCommand("ls; cd bin; ls");
| 归档时间: | 
 | 
| 查看次数: | 64229 次 | 
| 最近记录: |