Exécuter une commande sous Linux à l'aide de Java et de chercher la sortie
Je suis à l'aide de Groovy pour exécuter des commandes sur mon Linux et revenir de la sortie, mais je ne suis pas en mesure d'utiliser |
tuyaux en quelque sorte (je crois), ou peut-être qu'il n'est pas d'attente pour terminer la commande.
Ce qui est mal ou ce qui me manque dans mon code?
Mon appel de la fonction:
def test()
{
String result="N"
HashMap<String,String> params = IntermediateResults.get("userparams")
Map env=AppContext.get(AppCtxProperties.environmentVariables)
def fClass = new GroovyClassLoader().parseClass( new File( 'plugins/infa9/Infa9CommandExecUtil.groovy' ) )
List<String> frows=["uname -a",
"uname -a | awk '{print\$2}'",
"uname -a | cut -d ' ' -f 2"]
List<String> resultRows = fClass.newInstance().fetchCommandOutput( params, env, frows )
return result
}
Infa9CommandExecUtil.groovy
fichier de contenu (mise à jour: ajout de exitVal println):
package infa9
import java.io.BufferedReader;
public class Infa9CommandExecUtil {
StringBuffer result
public Infa9CommandExecUtil() {
result = new StringBuffer()
}
public List<String> fetchCommandOutput( Map<String,String> params, Map env, List<String> rows )
{
List<String> outputRows = new ArrayList<String>()
try
{
for(item in rows)
{
String temp=item.toString()
println "CMD:$temp"
Process proc = Runtime.getRuntime().exec(temp);
InputStream stdin = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(stdin);
BufferedReader br = new BufferedReader(isr);
String line = null;
result = new StringBuffer()
line=null
int exitVal = proc.waitFor() //do I need to wait for the thread/process to finish here?
while ((line = br.readLine()) != null)
{
result.append(line+System.getProperty("line.separator")) //to maintain the format (newlines)
}
String tRes=result
tRes=tRes.trim()
println "OUTPUT:$tRes\nEXITVAL:$exitVal"
outputRows.add(tRes)
}
}
catch (IOException io) { io.printStackTrace();}
catch (InterruptedException ie) {ie.printStackTrace();}
return outputRows
}
}
Ma sortie (mise à jour: ajout de exitVal valeur):
CMD:uname -a
OUTPUT:Linux estilo 2.6.18-128.el5 #1 SMP Wed Dec 17 11:41:38 EST 2008 x86_64 x86_64 x86_64 GNU/Linux
EXITVAL:0
CMD:uname -a | awk '{print$2}'
OUTPUT:
EXITVAL:1
CMD:uname -a | cut -d ' ' -f 2
OUTPUT:
EXITVAL:1
Note: je suis à l'interne à l'aide de sh -c <command>
.
Donc, vous n'êtes toujours pas le faire dans un Groovy façon (que je vous ai montré quelques fois)?
Je suis en retard, je pense que je vais d'abord répondre aux exigences et puis refactoriser le code. Désolé 🙂
Je voudrais lire le flux d'erreur ou d'utiliser ProcessBuilder d'erreur directe à la sortie. Je voudrais copier la sortie d'un ByteArrayOutputStream et de la conversion d'une Chaîne de caractères.
Lawrey: Pouvez-vous nous donner un exemple, il serait d'une grande aide. Merci
Je pensais que vous n'étiez pas censé appeler non les programmes Java de Java. Sinon, pourquoi s'embêter écrit en Java, en premier lieu?
Je suis en retard, je pense que je vais d'abord répondre aux exigences et puis refactoriser le code. Désolé 🙂
Je voudrais lire le flux d'erreur ou d'utiliser ProcessBuilder d'erreur directe à la sortie. Je voudrais copier la sortie d'un ByteArrayOutputStream et de la conversion d'une Chaîne de caractères.
Lawrey: Pouvez-vous nous donner un exemple, il serait d'une grande aide. Merci
Je pensais que vous n'étiez pas censé appeler non les programmes Java de Java. Sinon, pourquoi s'embêter écrit en Java, en premier lieu?
OriginalL'auteur abi1964 | 2011-11-08
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas faire des pipes ou des redirections à l'aide de
String.execute()
. Cela ne fonctionne pas en Java, donc il ne fonctionne pas en Groovy, soit...Vous pouvez utiliser
Process.pipeTo
avec Groovy pour simplifier les choses:Plus générique version pourrait être:
.inject(null)
etp,c->
fais ici?Le injecter de la méthode commence par un premier accumulateur de valeur (dans ce cas
null
), puis descend la Collection de l'application de la fermeture de chaque élément à son tour (la suite de la Fermeture se fait dans l'accumulateur pour l'élément suivant). Donc dans ce cas, nous commençons avecnull
, puis la première itération il définit àc.execute()
(où c est notre premier élément de la liste), puis de la deuxième boucle,p
est la résultante de Processus à partir de cela, et il définit l'accumulateur àp | c.execute()
. Espérons que cela a du sens?Comment êtes-vous capturer la sortie? Comme je vous l'ai montré dans un de vos autres questions?
la commande d'impression, la sortie ici?
Je ne comprends pas la question...
result.waitForProcessOutput( System.out, System.out )
redirige la sortie d'erreur et de flux de la chaine de processus deSystem.out
. Tout est alors indiqué sur le même cours d'eau...OriginalL'auteur tim_yates
La pipe
|
est une fonction du shell comme bash. L'utilisation d'un tuyau, vous devez exécuter une coquille, commeÀ utiliser ProcessBuilder avec la redirection que vous pouvez faire
imprime
OriginalL'auteur Peter Lawrey
Pipe est une fonction de l'interpréteur de commandes. Donc, si vous voulez des tuyaux pour être pris en charge, vous devez exécuter votre commande dans le shell contexte, par exemple, votre ligne de commande que vous passez à
exec
en java devrait ressembler à/bin/sh YOUR_COMMAND
.sh -c <command>
OriginalL'auteur AlexR