2016-02-03 12 views
10

Korzystanie z pomocy Groovy i jej obsługi java.lang.Process, w jaki sposób mogę połączyć wiele poleceń powłoki?Używając groovy, jak potokować polecenia wielu powłok?

Rozważmy to polecenie bash (a zakładamy, że nazwa jest foo):

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

ten wypisze nazwy użytkownika - jeden wiersz dla niektórych procesów związanych z kontem użytkownika.

Korzystanie Groovy, dokumentacja ProcessGroovyMethods i kod mówi, że powinienem być w stanie to zrobić, aby osiągnąć ten sam rezultat:

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

Jednak nie mogę uzyskać żadnych wyjście tekstu do niczego innego niż to:

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

Zaraz po uruchomieniu instalacji drukarka nie drukuje niczego.

Myśli?

Odpowiedz

8

Działa to dla mnie:

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

z nieznanego powodu, parametry awk nie można wysłać z tylko jednym ciągiem (nie wiem dlaczego! może bash cytuje coś inaczej). Jeśli zrzucasz z poleceniem strumień błędów, zobaczysz błąd związany z kompilacją skryptu awk.

Edit W rzeczywistości

  1. "-string-".execute() delegatem Runtime.getRuntime().exec(-string-)
  2. To zadanie bash obsługiwać argumenty zawierające spacje z "lub” Runtime.exec lub systemu operacyjnego nie są świadomi cytaty
  3. .
  4. Wykonywanie "grep ' foo'".execute() powoduje wykonanie polecenia grep, z ' jako pierwszymi parametrami, a foo' jako drugim parametrem: nie jest poprawne, tak samo dla awk
+0

Podczas gdy odpowiedź @ tim_yates rozwiązała mój szczególny problem w inny sposób (i jestem bardzo wdzięczny za to), ta odpowiedź odnosi się do pytania OP operatora 'lub' Groovy i 'Procesu 'obiekty, więc ją nagrodzę. Dzięki! –

8

Można to zrobić po prostu niech powłoki rozwiązać to:

// 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 
+0

Tak, mogłem, i że może być tak, jak trzeba iść, ale czy wiesz, dlaczego metoda „lub” nie działa, jak określono w docs? –

+1

To ma coś wspólnego z awk. Nie wiem co, ale nie podoba mi się bycie prowadzonym w ten sposób. –

+0

Interesujące - podejście szykowe zadziałało. Używanie podwójnych cudzysłowów nie miało miejsca. Domyśl! –

0

Jeśli chcesz asynchroniczny Polecam

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