【问题标题】:How to use "cd" command using Java runtime?如何在 Java 运行时使用“cd”命令?
【发布时间】:2011-06-20 13:24:41
【问题描述】:

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

谁能告诉我如何实现它?

【问题讨论】:

标签: java terminal runtime runtime.exec cd


【解决方案1】:

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

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

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

当前工作目录很重要的一种情况是执行外部进程(使用ProcessBuilderRuntime.exec())。在这些情况下,您可以明确指定用于新启动进程的工作目录(分别为ProcessBuilder.directory()three-argument Runtime.exec())。

注意:当前工作目录可以从system propertyuser.dir读取。您可能会想设置该系统属性。注意这样做会导致very bad inconsistencies,因为it's not meant to be writable

【讨论】:

  • 我正在使用 runtime.exec()。你能告诉我如何明确指定工作目录吗?
  • @Jigar 我之前已经看到过这个问题。但该解决方案使用 Executer 但我只想使用 Runtime。
  • 使用 Runtime.getRuntime.exec("cmd /c cd path");它会工作
  • 工作感谢@DheerajSachan 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);
【解决方案2】:

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

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

即:

String[] cmd = { "/bin/sh", "-c", "cd /var; ls -l" };
Process p = Runtime.getRuntime().exec(cmd);

【讨论】:

    【解决方案3】:

    您是否为 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
    

    【讨论】:

    • 这应该是我认为的答案
    • 是的,这是对我有用的答案:但是,请记住,需要指定 File dir 参数并包含最后一个斜杠。例如:文件 dir = new File("C:\\l\\workspace\\myproject\\mydirectory\\");
    【解决方案4】:

    这个命令很好用

    Runtime.getRuntime().exec(sh -c 'cd /path/to/dir && ProgToExecute)
    

    【讨论】:

    • 我不关注不应该是Runtime.getRuntime().exec("sh -c 'cd /path/to/dir && ProgToExecute'")吗?这将返回退出代码2
    【解决方案5】:

    尝试使用:

    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

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

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

        ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", cmd).directory(new File(path));
        
                Process p = builder.start();
        
                p.waitFor(timeoutSec, TimeUnit.SECONDS);
        

        在上面的代码中,可以将path[我们期望cmd执行的地方]的file对象传递给ProcessBuilder

        的directory方法

        【讨论】:

          【解决方案8】:

          我首选的解决方案是传入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.
          

          【讨论】:

            猜你喜欢
            • 2012-04-09
            • 2012-09-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-28
            • 2013-07-11
            相关资源
            最近更新 更多