2010-06-22 3 views
1

Я пытаюсь выполнить следующую команду в моей программе JavaОшибка во время выполнения команды Линукс через Runtime.getRuntime(). EXEC

Runtime.getRuntime().exec("ls -lrt service/logs/post/level2.log | awk '{print $9}'"); 
or 
Runtime.getRuntime().exec("ls -lrt service/logs/post/level2* | awk '{print $9}'"); 

это дает мне следующее сообщение об ошибке

 
ls: 0653-341 The file | does not exist. 
ls: 0653-341 The file awk does not exist. 
ls: 0653-341 The file '{print does not exist. 
ls: 0653-341 The file $9}' does not exist. 

Пожалуйста, помогите мне

ответ

9

Трубы представляют собой оболочечную конструкцию, а не текущие управляемые команды. Есть два варианта сделать это, как я вижу:

  1. Сделайте трубопровод самостоятельно на Java. Сначала вызовите команду ls, получите дескриптор к его OutputStream, а затем вызовите awk, соединяющий первый вывод Process со вторым входным потоком Process.
  2. Вызываем оболочку bash непосредственно из Java, передавая всю команду в качестве аргумента для параметра bash's -c. Таким образом, весь трубопровод выполняется в пределах единственного процесса.

Что касается ошибок на основе токенов, вы должны вызывать эти команды с помощью массива строк; каждый элемент представляет собой токен командной строки. Поэтому попробуйте, например:

Runtime.getRuntime().exec(new String[] { "ls", "-lrt", "service/logs/post/level2.log" }); 

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


Редактировать (в ответ на комментарии): В первом варианте, я просто имел в виду, что вы в состоянии трубы выход между этими двумя процессами самостоятельно, в Java.

Представьте себе, если вы создали процесс, как так:

Process ls = Runtime.getRuntime().exec("ls -lrt service/logs/post/level2.log"); 

Теперь этот процесс будет работать и генерировать некоторый вывод (который мы знаем, будет строка, описывающая этот файл). Мы можем получить поток для этого выхода, как так:

InputStream lsOut = ls.getInputStream(); 

Теперь мы хотим, чтобы запустить этот процесс AWK:

Process awk = Runtime.getRuntime().exec(new String[] { "awk", "{print $9}"}); 

Процесс AWK, конечно, будет сидеть в момент ожидания ввода, поскольку он знает, что это будет чтение из stdin.Таким образом, мы захватываем входной поток, который он собирается использовать:

OutputStream awkIn = awk.getOutputStream(); 

Теперь немного труб - мы читаем вывод команды LS и передать его на вход для AWK:

// TODO add buffering, error handling, probably run this in a separate thread 
int datum = lsOut.read(); 
while (datum != -1) 
{ 
    awkIn.write(datum); 
    datum = lsOut.read(); 
} 

Это читает вывод ls (байт по-байт для простоты, использование буферов массива байтов будет намного быстрее, но я просто хочу проиллюстрировать это понятие) и записывает его на вход awk.

Тогда это просто вопрос считывания вывода из процесса awk и решение его по своему усмотрению.

+0

Извините, дорогая, я не могу подстать немного любезно помочь. – user369151

+0

Мне нужно понять, что первый результат процесса обрабатывается во втором потоке ввода процесса. – user369151

+0

@Andrzej Doyle: Просто хочу проверить: будет ли выполняться Runtime.getRuntime(). Exec ("file.sh") работает или нет? – Xorty

Смежные вопросы