Как вызвать unix-скрипт из java?

Я хочу удалить старые файлы журналов в каталоге журналов. Чтобы удалить файлы журнала более 6 месяцев, Я написал сценарий как

найти / dnbusr1 / ghmil / BDELogs / import -type f -mtime +120 -exec rm -f {} \;

Используя этот скрипт, я могу удалить старые файлы, но как мне вызвать этот скрипт с помощью java?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
1 083
5

Ответы 5

Используйте java.lang.Runtime.exec ().

Если вы собираетесь использовать это, вы можете прочитать это: javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html.

Sophie Alpert 23.01.2009 07:33

@Ben: Я не согласен с этой статьей. Автор статьи, судя по тому, что я прочитал со страницы 1, понятия не имеет, как работают процессы Unix. Конечно, вам нужно дождаться процесса, прежде чем вы получите возвращаемое значение! (Это также не способ автоматического ожидания в Unix; программа должна это запрашивать.)

Chris Jester-Young 23.01.2009 07:37

@Ben: 2-я и 3-я страницы лучше, говоря о необходимости обрабатывать любой ввод и вывод, который требует / генерирует программа. Очевидно, что их следует настроить (возможно, в отдельном потоке) перед ожиданием.

Chris Jester-Young 23.01.2009 07:40

@Ben: В целом, мне кажется, что эта статья касается только программирования для Windows. На странице 4 подводные камни использования команд оболочки и перенаправления известны многим программистам Unix, которые будут / должны использовать ['sh', '-c', cmdstring] всякий раз, когда требуется функциональность оболочки.

Chris Jester-Young 23.01.2009 07:42

Имейте в виду, я скажу, что для программистов Windows, использующих Java, эта статья действительно очень полезна и ее следует рекомендовать. Так что мои комментарии о неприменимости этой статьи к Unix никоим образом не должны рассматриваться как принижающие значение статьи в целом.

Chris Jester-Young 23.01.2009 07:48

Использование системных вызовов в Java возможно, но, как правило, это плохая идея, поскольку вы потеряете переносимость кода. Вы можете заглянуть в Муравей и использовать что-то вроде этого задача очистки.

Добавляя к ответу Crashworks, вы вызываете эти аргументы в cmdarray:

new String[] {"find", "/dnbusr1/ghmil/BDELogs/import", "-type", "f",
    "-mtime", "+120", "-exec", "rm", "-f", "{}", ";"}

Если ваш find поддерживает синтаксис -exec ... {} +, замените ";" в конце на "+". Это заставит вашу команду работать быстрее (она вызовет rm для пакета файлов сразу, а не один раз для каждого файла).

Если переносимость является проблемой, не позволяющей запускать Runtime.exec (), этот код довольно просто написать на Java с использованием File и FilenameFilter.

Обновлено: вот статический метод удаления дерева каталогов ... вы можете достаточно легко добавить в логику фильтрации:

static public int deleteDirectory(File dir, boolean slf) {
    File[]                              dc;                                     // directory contents
    String                              dp;                                     // directory path
    int                                 oc=0;                                   // object count

    if (dir.exists()) {
        dir=dir.getAbsoluteFile();

        if (!dir.canWrite()) {
            throw new IoEscape(IoEscape.NOTAUT,"Not authorized to delete directory '"+dir+"'.");
            }

        dp=dir.getPath();
        if (dp.equals("/") || dp.equals("\\") || (dp.length()==3 && dp.charAt(1)==':' && (dp.charAt(2)=='/' || dp.charAt(2)=='\\'))) {
            // Prevent deletion of the root directory just as a basic restriction
            throw new IoEscape(IoEscape.GENERAL,"Cannot delete root directory '"+dp+"' using IoUtil.deleteDirectory().");
            }

        if ((dc=dir.listFiles())!=null) {
            for(int xa=0; xa<dc.length; xa++) {
                if (dc[xa].isDirectory()) {
                    oc+=deleteDirectory(dc[xa]);
                    if (!dc[xa].delete()) { throw new IoEscape(IoEscape.GENERAL,"Unable to delete directory '"+dc[xa]+"' - it may not be empty, may be in use as a current directory, or may have restricted access."); }
                    }
                else {
                    if (!dc[xa].delete()) { throw new IoEscape(IoEscape.GENERAL,"Unable to delete file '"+dc[xa]+"' - it may be currently in use by a program, or have restricted access."); }
                    }
                oc++;
                }
            }

        if (slf) {
            if (!dir.delete()) { throw new IoEscape(IoEscape.GENERAL,"Unable to delete directory '"+dir+"' - it may not be empty, may be in use as a current directory, or may have restricted access."); }
            oc++;
            }
        }
    return oc;
    }

Если вы хотите вызвать только описанную вами команду, вызовите:

Runtime r = Runtime.getRuntime();
Process process = r.exec("find /dnbusr1/ghmil/BDELogs/import -type f -mtime +120 -exec rm -f {} \\;"); //$NON-NLS-1$
process.waitFor();

Если вы хотите вызвать более одной команды, используйте ответ Криса Джестера-Янга. Метод exec также может определять файлы, которые вы хотите использовать. Другие ответы ссылаются на описание метода.

Лично я достаточно сильно ненавижу цитирование метасимволов оболочки, только с помощью сценариев оболочки; когда мне приходится делать то же самое с вызовом system / exec на других языках, я чувствую необходимость вырвать себе глаза. :-P Следовательно, я обычно предпочитаю явно указывать значения argv. :-)

Chris Jester-Young 23.01.2009 17:05

Другие вопросы по теме