56

我创建了一个独立的 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

谁能告诉我如何实现它?

4

8 回答 8

66

没有名为 的可执行文件cd,因为它不能在单独的进程中实现。

问题是每个进程都有自己的当前工作目录,并且cd作为单独的进程实现只会更改进程的当前工作目录。

在 Java 程序中,您不能更改当前的工作目录,也不需要这样做。只需使用绝对文件路径。

当前工作目录很重要的一种情况是执行外部进程(使用ProcessBuilderor Runtime.exec())。在这些情况下,您可以显式指定用于新启动进程的工作目录(分别ProcessBuilder.directory()三个参数Runtime.exec())。

注意:当前工作目录可以从系统属性 user.dir中读取。您可能想设置该系统属性。请注意,这样做会导致非常严重的不一致,因为它不是的。

于 2011-02-03T10:05:23.383 回答
21

请参阅下面的链接(这说明了如何操作):

http://alvinalexander.com/java/edu/pj/pj010016

IE :

String[] cmd = { "/bin/sh", "-c", "cd /var; ls -l" };
Process p = Runtime.getRuntime().exec(cmd);
于 2014-01-14T17:44:54.713 回答
14

您是否为 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(command) 创建的 StringTokenizer 将命令字符串分解为标记,而无需进一步修改字符类别。标记器生成的标记然后以相同的顺序放置在新的字符串数组 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
于 2014-07-18T07:24:14.913 回答
6

这个命令工作得很好

Runtime.getRuntime().exec(sh -c 'cd /path/to/dir && ProgToExecute)
于 2015-04-04T17:47:50.260 回答
2

使用流程构建器的方法之一,我们可以传递我们期望执行 cmd 的目录。请看下面的例子。此外,您可以使用等待方法提及进程的超时。

ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", cmd).directory(new File(path));

        Process p = builder.start();

        p.waitFor(timeoutSec, TimeUnit.SECONDS);

在上面的代码中,您可以将路径[我们期望执行cmd的位置]的文件对象传递给ProcessBuilder的目录方法

于 2018-11-10T21:59:08.027 回答
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

于 2017-04-05T16:28:13.213 回答
1

我首选的解决方案是传入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 库,即添加到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.
于 2021-06-28T15:32:45.170 回答
0

我通过让 Java 应用程序执行一个位于同一目录中的 sh 脚本,然后在 sh 脚本中完成了“cd”来解决了这个问题。

要求我对特定目录执行“cd”,以便目标应用程序可以正常工作。

于 2017-05-03T19:19:02.400 回答