我创建了一个独立的java应用程序,我正在尝试使用Ubuntu 10.04终端中的“cd”命令更改目录。我使用了以下代码。
String[] command = new String[]{"cd",path};
Process child = Runtime.getRuntime().exec(command, null);
但是上面的代码给出了以下错误
Exception in thread "main" java.io.IOException: Cannot run program "cd": java.io.IOException: error=2, No such file or directory
有谁能告诉我如何实施它?
答案 0 :(得分:55)
没有名为cd
的可执行文件,因为无法在单独的进程中实现。
问题是每个进程都有自己的当前工作目录,而实现cd
作为一个单独的进程只会改变那个处理当前工作目录。
在Java程序中,无法更改当前的工作目录,您不需要这样做。只需使用绝对文件路径。
当前工作目录很重要的一种情况是执行外部流程(使用ProcessBuilder
或Runtime.exec()
)。在这些情况下,您可以明确指定用于新启动的流程的工作目录(分别为ProcessBuilder.directory()
和three-argument Runtime.exec()
)。
注意:可以从system property user.dir
读取当前工作目录。您可能会想要设置该系统属性。请注意,这样做会导致very bad inconsistencies,因为it's not meant to be writable。
答案 1 :(得分:15)
请参阅以下链接(这解释了如何操作):
http://alvinalexander.com/java/edu/pj/pj010016
即。 :
String[] cmd = { "/bin/sh", "-c", "cd /var; ls -l" };
Process p = Runtime.getRuntime().exec(cmd);
答案 2 :(得分:12)
您是否已为java运行时探索此exec命令,使用您想要“cd”的路径创建文件对象,然后将其作为exec方法的第三个参数输入。
public Process exec(String command,
String[] envp,
File dir)
throws IOException
在具有指定环境和工作目录的单独进程中执行指定的字符串命令。
这是一种方便的方法。调用exec(command,envp,dir)的形式与调用exec(cmdarray,envp,dir)完全相同,其中cmdarray是命令中所有标记的数组。
更准确地说,命令字符串使用由调用new StringTokenizer(命令)创建的StringTokenizer分解为标记,而不进一步修改字符类别。然后,由tokenizer生成的标记以相同的顺序放置在新的字符串数组cmdarray中。
Parameters:
command - a specified system command.
envp - array of strings, each element of which has environment variable settings in the format name=value, or null if the subprocess should inherit the environment of the current process.
dir - the working directory of the subprocess, or null if the subprocess should inherit the working directory of the current process.
Returns:
A new Process object for managing the subprocess
Throws:
SecurityException - If a security manager exists and its checkExec method doesn't allow creation of the subprocess
IOException - If an I/O error occurs
NullPointerException - If command is null, or one of the elements of envp is null
IllegalArgumentException - If command is empty
答案 3 :(得分:7)
此命令可以正常工作
Runtime.getRuntime().exec(sh -c 'cd /path/to/dir && ProgToExecute)
答案 4 :(得分:1)
尝试使用:
Runtime.getRuntime.exec("cmd /c cd path");
这有效
Runtime r = Runtime.getRuntime();
r.exec("cmd /c pdftk C:\\tmp\\trashhtml_to_pdf\\b.pdf C:\\tmp\\trashhtml_to_pdf\\a.pdf cat output C:\\tmp\\trashhtml_to_pdf\\d.pdf");
以下无效 使用数组命令时没有工作
String[] cmd = {"cmd /c pdftk C:\\tmp\\trashhtml_to_pdf\\b.pdf C:\\tmp\\trashhtml_to_pdf\\a.pdf cat output C:\\tmp\\trashhtml_to_pdf\\d.pdf"}; r.exec(cmd);
我们正在使用实用程序检查操作系统,如果上面的窗口不适用于Windows除 cmd 和 / c
答案 5 :(得分:1)
使用流程生成器的一种方法,我们可以将目录传递到我们希望执行cmd的目录。请参见以下示例。另外,您可以使用wait方法提及进程的超时。
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", cmd).directory(new File(path));
Process p = builder.start();
p.waitFor(timeoutSec, TimeUnit.SECONDS);
在上面的代码中,您可以将路径[我们希望执行cmd的位置]的文件对象传递给 ProcessBuilder
的目录方法答案 6 :(得分:0)
我已经解决了这个问题,让Java应用程序执行一个位于同一目录下的sh脚本,然后在sh脚本中执行了“cd”。
我需要对特定目录执行“cd”,以便目标应用程序可以正常工作。
答案 7 :(得分:0)
对此我的首选解决方案是传入 Runtime
进程将在其中运行的目录。我将创建一个如下所示的小方法:-
public static String cmd(File dir, String command) {
System.out.println("> " + command); // better to use e.g. Slf4j
System.out.println();
try {
Process p = Runtime.getRuntime().exec(command, null, dir);
String result = IOUtils.toString(p.getInputStream(), Charset.defaultCharset());
String error = IOUtils.toString(p.getErrorStream(), Charset.defaultCharset());
if (error != null && !error.isEmpty()) { // throw exception if error stream
throw new RuntimeException(error);
}
System.out.println(result); // better to use e.g. Slf4j
return result; // return result for optional additional processing
} catch (IOException e) {
throw new RuntimeException(e);
}
}
请注意,这使用了 Apache Commons IO library,即添加到 pom.xml
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.10.0</version>
</dependency>
使用 cmd
方法,例如
public static void main(String[] args) throws Exception {
File dir = new File("/Users/bob/code/test-repo");
cmd(dir, "git status");
cmd(dir, "git pull");
}
这将输出如下内容:-
> git status
On branch main
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
> git pull
Already up to date.