您开始一个新流程Runtime.exec(command)
。每个进程都有一个工作目录。这通常是启动父进程的目录,但您可以更改启动进程的目录。
我建议使用流程构建器 https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html
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 这样的模板引擎也可能是合理的。
EDIT
您还应该考虑将流程构建器的复杂性隐藏在简单的界面后面。
将您需要的内容(接口)与其完成方式(实现)分开。
public interface FileUtils {
public String[] listFiles(String dirpath);
}
然后,您可以提供使用进程构建器或本机方法来完成工作的实现,并且可以为不同的环境(如 Linux 或 Windows)提供不同的实现。
最后,这样的接口也更容易在单元测试中模拟。