Как использовать команду cd во время выполнения Java?

Я создал автономное Java-приложение, в котором я пытаюсь изменить каталог с помощью команды «cd» в терминале Ubuntu 10.04. Я использовал следующий код.

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

Может ли кто-нибудь сказать мне, как это реализовать?


person Antrromet    schedule 03.02.2011    source источник
comment
Выход состоял в том, чтобы запустить новую оболочку и запустить все свои команды - webmasterworld.com/linux/3613813 .htm   -  person letsc    schedule 12.11.2011


Ответы (8)


Исполняемого файла с именем cd не существует, поскольку его нельзя реализовать в отдельном процессе.

Проблема в том, что у каждого процесса есть свой текущий рабочий каталог, и реализация cd в качестве отдельного процесса будет когда-либо изменять только который обрабатывает текущий рабочий каталог.

В программе на Java вы не можете изменить текущий рабочий каталог, и вам это не нужно. Просто используйте абсолютные пути к файлам.

Единственный случай, когда текущий рабочий каталог имеет значение, — это выполнение внешнего процесса (с использованием ProcessBuilder или Runtime.exec()). В таких случаях вы можете явно указать рабочий каталог для вновь запущенного процесса (ProcessBuilder.directory() и три аргумента Runtime.exec() соответственно).

Примечание: текущий рабочий каталог можно прочитать из системное свойство user.dir. У вас может возникнуть соблазн установить это системное свойство. Обратите внимание, что это приведет к очень серьезным несоответствиям, потому что он не предназначен для записи.

person Joachim Sauer    schedule 03.02.2011
comment
Я использую runtime.exec(). Можете ли вы сказать мне, как явно указать рабочий каталог? - person Antrromet; 03.02.2011
comment
@Antro stackoverflow.com/questions/544519/ - person jmj; 03.02.2011
comment
@Jigar Я уже видел этот вопрос раньше. Но решение использует Executer, но я хочу использовать только Runtime. - person Antrromet; 03.02.2011
comment
используйте Runtime.getRuntime.exec (путь cmd/c cd); это будет работать - person Dheeraj Sachan; 05.04.2017
comment
Работает, спасибо @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); - person shareef; 21.08.2017
comment
@shareef мой ответ ниже, несколько ответов сдаются, так что в конце концов он появляется. - person Dheeraj Sachan; 21.08.2017
comment
@JoachimSauer: Вам не нужно: НЕПРАВИЛЬНО. НИКОГДА НЕ ПРЕДПОЛОЖАЙТЕ, что нужно чужому коду, если только вы не являетесь поставщиком нестандартной функции. Даже в этом случае вы можете ошибаться, но вы не можете изменить стандарт, поэтому они и называются стандартами. Изменить каталог — стандартная функция дисковой операционной системы. Тот факт, что вы не можете изменить текущий каталог, препятствует эффективному использованию файлового объекта Java в программах, подобных оболочкам, и интерпретаторах сценариев. См. этот пост - person Hypersoft Systems; 05.12.2017

См. ссылку ниже (здесь объясняется, как это сделать):

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

i.e. :

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

Изучили ли вы эту команду exec для среды выполнения java. Создайте файловый объект с путем, по которому вы хотите «cd», а затем введите его в качестве третьего параметра для метода exec.

public Process exec(String command,
                String[] envp,
                File dir)
         throws IOException

Выполняет указанную строковую команду в отдельном процессе с указанной средой и рабочим каталогом.

Это метод удобства. Вызов формы exec(command, envp, dir) ведет себя точно так же, как вызов exec(cmdarray, envp, dir), где cmdarray — это массив всех токенов в команде.

Точнее, командная строка разбивается на токены с помощью StringTokenizer, созданного вызовом new StringTokenizer(command) без дальнейшего изменения категорий символов. Маркеры, созданные токенизатором, затем помещаются в новый массив строк 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
person deepak.prathapani    schedule 18.07.2014
comment
Это должен быть ответ, я думаю - person Gun2sh; 22.12.2016
comment
Да, это ответ, который сработал для меня: однако имейте в виду, что параметр File dir должен быть указан с включенной последней косой чертой. Например: File dir = new File(C:\\l\\workspace\\myproject\\mydirectory\\); - person Tihamer; 19.08.2020

Эта команда работает просто отлично

Runtime.getRuntime().exec(sh -c 'cd /path/to/dir && ProgToExecute)
person mateusz.zbikowski    schedule 04.04.2015
comment
Я не понимаю, разве это не должно быть Runtime.getRuntime().exec("sh -c 'cd /path/to/dir && ProgToExecute'")? Это возвращает код выхода 2 - person lisak; 12.07.2016

Используя один из методов построителя процессов, мы можем передать каталог, в котором, как мы ожидаем, будет выполняться cmd. См. приведенный ниже пример. Кроме того, вы можете указать время ожидания для процесса, используя метод ожидания.

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

        Process p = builder.start();

        p.waitFor(timeoutSec, TimeUnit.SECONDS);

В приведенном выше коде вы можете передать файловый объект пути [где мы ожидаем, что cmd будет выполнена] в метод каталога ProcessBuilder

person TechDog    schedule 10.11.2018

Попробуйте использовать:

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);

К вашему сведению, я использую утилиту для проверки ОС, будут ли ее окна выше работать для других, кроме удаления окон cmd и /c

person Dheeraj Sachan    schedule 05.04.2017

Я решил эту проблему, заставив приложение Java выполнить сценарий sh, который находился в том же каталоге, а затем в сценарии sh выполнил «cd».

Требовалось, чтобы я сделал «cd» для определенного каталога, чтобы целевое приложение могло работать правильно.

person Rami Del Toro    schedule 03.05.2017

Мое предпочтительное решение для этого — передать каталог, в котором будет работать процесс 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, т. е. добавление в 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.
person bobmarksie    schedule 28.06.2021