Как заставить трубы работать с Runtime.exec ()?

Рассмотрим следующий код:

String commandf = "ls /etc | grep release"; try { // Execute the command and wait for it to complete Process child = Runtime.getRuntime().exec(commandf); child.waitFor(); // Print the first 16 bytes of its output InputStream i = child.getInputStream(); byte[] b = new byte[16]; i.read(b, 0, b.length); System.out.println(new String(b)); } catch (IOException e) { e.printStackTrace(); System.exit(-1); } 

Выход программы:

 /etc: adduser.co 

Разумеется, когда я бегу от оболочки, она работает так, как ожидалось:

 [email protected]:~/rabbit_test$ ls /etc | grep release lsb-release 

Интернеты говорят мне, что из-за того, что поведение труб не является кросс-платформенным, блестящие умы, которые работают на фабрике Java, производящей Java, не могут гарантировать работу труб.

Как я могу это сделать?

Я не собираюсь выполнять весь мой синтаксический анализ, используя конструкторы Java, а не grep и sed , потому что, если я хочу изменить язык, я буду вынужден повторно написать мой синтаксический код на этом языке, идти.

Как я могу заставить Java выполнять коммутацию и redirect при вызове команд оболочки?

Напишите сценарий и выполните сценарий вместо отдельных команд.

Труба является частью оболочки, поэтому вы также можете сделать что-то вроде этого:

 String[] cmd = { "/bin/sh", "-c", "ls /etc | grep release" }; Process p = Runtime.getRuntime().exec(cmd); 

Я столкнулся с аналогичной проблемой в Linux, за исключением того, что это был «ps -ef | grep someprocess».
По крайней мере, с «ls» у вас есть независимая от языка (хотя и медленная) замена Java. Например.:

 File f = new File("C:\\"); String[] files = f.listFiles(new File("/home/tihamer")); for (String file : files) { if (file.matches(.*some.*)) { System.out.println(file); } } 

С «ps» это немного сложнее, потому что Java, похоже, не имеет API для него.

Я слышал, что Sigar может помочь нам: https://support.hyperic.com/display/SIGAR/Home

Однако самое простое решение (как указано Kaj) заключается в том, чтобы выполнить команду piped как строковый массив. Вот полный код:

 try { String line; String[] cmd = { "/bin/sh", "-c", "ps -ef | grep export" }; Process p = Runtime.getRuntime().exec(cmd); BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); while ((line = in.readLine()) != null) { System.out.println(line); } in.close(); } catch (Exception ex) { ex.printStackTrace(); } 

Что касается того, почему массив String работает с каналом, в то время как одна строка не … это одна из загадок вseleniumной (особенно если вы не читали исходный код). Я подозреваю, что это потому, что, когда exec задана одна строка, она сначала анализирует ее (таким образом, что нам не нравится). Напротив, когда exec задан строковый массив, он просто передает его операционной системе без его parsingа.

Фактически, если мы выберем время из напряженного дня и посмотрим на исходный код (по адресу http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/ Runtime.java # Runtime.exec% 28java.lang.String% 2Cjava.lang.String []% 2Cjava.io.File% 29 ), мы находим, что это именно то, что происходит:

 public Process [More ...] exec(String command, String[] envp, File dir) throws IOException { if (command.length() == 0) throw new IllegalArgumentException("Empty command"); StringTokenizer st = new StringTokenizer(command); String[] cmdarray = new String[st.countTokens()]; for (int i = 0; st.hasMoreTokens(); i++) cmdarray[i] = st.nextToken(); return exec(cmdarray, envp, dir); } 

Создайте Runtime для запуска каждого из процессов. Получите OutputStream с первого времени выполнения и скопируйте его в InputStream со второго.

  • java Runtime.getRunTime (). exec & wildcards?
  • Выполнение внешней программы в java
  • Метод exec () Runtime не перенаправляет вывод
  • Запуск java-программы из другой java-программы
  • Перенаправить Runtime.getRuntime (). Exec () с помощью System.setOut ();
  • Запуск командной строки в Java
  • как скомпилировать и запустить java-программу в другой Java-программе?
  • Runtime.getRuntime (). Exec ()
  • Как решить "java.io.IOException: ошибка = 12, Невозможно выделить память" вызов Runtime # exec ()?
  • Interesting Posts

    Поместить контент в объект HttpResponseMessage?

    Java null проверить, почему use == вместо .equals ()

    PDF – Какое программное обеспечение для заполнения / заполнения формы PDF?

    Создание SearchView, который выглядит как руководство по разработке материалов

    API Карт Google превысил ограничение на количество пользователей в секунду

    WPF StringFormat = {0: C}, показывающий как доллары

    Objective-C: `@synthesize fooBar;` vs. `@synthesize fooBar = _fooBar;`

    Как получить прокручиваемый ListView?

    Как я могу печатать XML-источник, используя VB6 и MSXML?

    Кнопка загрузки элемента загрузки блогов загрузки Twitter

    SSH для компьютера с общим общедоступным IP-адресом и без прав администратора по маршрутизатору

    Выполните несколько команд с тем же процессом, используя .NET.

    Есть ли способ расщепления приложений Metro в Windows 8?

    Установка приоритета для streamов Java

    Как виртуальное наследование разрешает двусмысленность «бриллиантов» (множественное наследование)?

    Давайте будем гением компьютера.