Используя groovy, как вы обрабатываете несколько команд оболочки?

Используя Groovy и поддержку java.lang.Process, как я могу объединить несколько команд оболочки?

Рассмотрим эту команду bash (и предположим, что ваше имя пользователя foo):

ps aux | grep ' foo' | awk '{print $1}'

Это будет печатать имена пользователей - одна строка для некоторых процессов, связанных с вашей учетной записью пользователя.

Используя Groovy, документация и код ProcessGroovyMethods говорят, что я должен сделать это для достижения того же результата:

def p = "ps aux".execute() | "grep ' foo'".execute() | "awk '{print $1}'".execute()
p.waitFor()
println p.text

Однако я не могу получить какой-либо текст для чего-либо другого:

def p = "ps aux".execute()
p.waitFor()
println p.text

Как только я запустил трубопровод, println ничего не распечатывает.

Мысли?

Ответ 1

Это работает для меня:

def p = 'ps aux'.execute() | 'grep foo'.execute() | ['awk', '{ print $1 }'].execute()
p.waitFor()
println p.text

по неизвестной причине, параметры awk не могут быть отправлены только с одной строкой (я не знаю, почему! возможно, bash цитирует что-то по-другому). Если вы сбросите с помощью команды поток ошибок, вы увидите ошибку относительно компиляции awk script.

Изменить. Фактически,

  • "-string-".execute() делегировать Runtime.getRuntime().exec(-string-)
  • Это bash задание для обработки аргументов, содержащих пробелы с "или". Runtime.exec или ОС не знают о кавычках
  • Выполнение "grep ' foo'".execute() выполнить команду grep, с ' в качестве первых параметров и foo' как вторую: она недействительна. то же самое для awk

Ответ 2

Вы можете сделать это, чтобы разрешить оболочку:

// slash string at the end so we don't need to escape ' or $
def p = ['/bin/bash', '-c', /ps aux | grep ' foo' | awk '{print $1}'/].execute()
p.waitFor()
println p.text

Ответ 3

Если вы хотите его асинхронно, я рекомендую

 proc.consumeProcessOutputStream(new LineOrientedOutputStream() {
        @Override
        protected void processLine(String line) throws IOException {
           println line
        }
    }
    );