À l’aide de Groovy et de sa prise en charge Java.lang.Process
, comment canaliser plusieurs commandes Shell ensemble?
Considérez cette commande bash (en supposant que votre nom d'utilisateur est foo
):
ps aux | grep ' foo' | awk '{print $1}'
Cela affichera les noms d'utilisateur - une ligne pour certains processus liés à votre compte d'utilisateur.
En utilisant Groovy, le ProcessGroovyMethods documentation et code dit que je devrais pouvoir le faire pour obtenir le même résultat:
def p = "ps aux".execute() | "grep ' foo'".execute() | "awk '{print $1}'".execute()
p.waitFor()
println p.text
Cependant, je ne peux obtenir aucune sortie de texte pour autre chose que ceci:
def p = "ps aux".execute()
p.waitFor()
println p.text
Dès que je lance la tuyauterie, l’imprimante n’imprime rien.
Pensées?
Cela fonctionne pour moi:
def p = 'ps aux'.execute() | 'grep foo'.execute() | ['awk', '{ print $1 }'].execute()
p.waitFor()
println p.text
pour une raison inconnue, les paramètres de awk ne peuvent pas être envoyés avec une seule chaîne (je ne sais pas pourquoi! peut-être que bash cite quelque chose différemment). Si vous exportez le flux d’erreurs avec votre commande, vous verrez une erreur relative à la compilation du script awk.
Edit : En fait,
"-string-".execute()
délégué à Runtime.getRuntime().exec(-string-)
"grep ' foo'".execute()
exécute la commande grep, avec '
en tant que premier paramètre et foo'
en tant que second: ce n'est pas valide. la même chose pour awkVous pouvez le faire pour laisser le shell le résoudre:
// 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
Cela a fonctionné pour moi
def command = '''
ps aux | grep bash | awk '{print $1}'
'''
def proc = ['bash', '-c', command].execute()
proc.waitFor()
println proc.text
Si vous souhaitez exécuter plusieurs commandes, vous pouvez l'ajouter à la commande.
def command = '''
ls -ltr
cat secret
'''
def proc = ['bash', '-c', command].execute()
proc.waitFor()
println proc.text
Si vous le voulez async je le recommande
proc.consumeProcessOutputStream(new LineOrientedOutputStream() {
@Override
protected void processLine(String line) throws IOException {
println line
}
}
);