J'essaie d'exécuter une requête de recherche Elastic dans mon code java. je veux que le code soit exécuté sur ma machine en utilisant le shell bash.
Voici mon code:
public class Elastic { public static void main(String[] args) { String cmd = "curl -X PUT IP:PORT/twitter/_doc/10 -H 'Content-Type: application/json' -d '{ \"user\" : \"Bob\", \"post_date\" : \"2019-12-15T14:12:10\", \"message\" : \"trying out Elasticsearch\" }' "; try { Process pr = Runtime.getRuntime().exec(cmd); } catch (Exception e) { e.printStackTrace(); } /* try { Runtime.getRuntime().exec("/bin/bash "+"-c "+"\'"+cmd+"\'"); } catch (Exception e) { e.printStackTrace(); } */ System.out.println("==============="); System.out.println(cmd); } }
J'ai essayé de le faire de deux manières différentes, comme vous pouvez le voir dans le code qui a été commenté.
J'imprime la requête que j'ai construite afin de la vérifier. Lorsque j'exécute ce programme sur ma machine locale et que j'essaye la requête imprimée dans le terminal, cela fonctionne, mais pas dans ma requête java code / bash. Je suppose que cela a quelque chose à voir avec le formatage et l'utilisation de guillemets simples, mais je n'ai pas encore pu l'exécuter directement à partir de mon code.
3 Réponses :
Il peut être difficile de séparer correctement les arguments et de les citer correctement en utilisant uniquement Runtime.exec
.
Je vous recommande de jeter un œil au API ProcessBuilder si vous devez passer des arguments complexes comme json.
Vous pouvez essayer d'écrire le script dans un fichier séparé, puis utiliser
Process procBuildScript = new ProcessBuilder("path/to/myScript.sh", "myArg1 myArg2").start();
Si vous souhaitez également ajouter des paramètres, vous pouvez utiliser quelque chose comme
String[] cmdScript = new String[]{"/bin/bash", "path/to/myScript.sh"}; Process procScript = Runtime.getRuntime().exec(cmdScript);
Aussi bonne idée d'attendre à moins que le processus enfant se termine . Et puis vérifiez le code de sortie a>
@CobraKai Heureux d'avoir pu aider. Puisque votre problème a été résolu, veuillez marquer la réponse comme acceptée. Cela fera apparaître le message comme une réponse et peut aider d'autres personnes ayant un problème similaire.
Meilleure approche
Veuillez consulter les autres réponses pour des suggestions sur une approche tout à fait meilleure.
Comment corriger cette approche p >
Voici la citation correcte (et délicate) pour votre approche actuelle:
String cmd = "curl -X PUT IP:PORT/twitter/_doc/10 -H '"\'"'Content-Type: application/json'"\'"' -d '"\'"'{ \"user\" : \"Bob\", \"post_date\" : \"2019-12-15T14:12:10\", \"message\" : \"trying out Elasticsearch\" }'"\'"' "; [...] Runtime.getRuntime().exec("/bin/bash "+"-c "+"'"+cmd+"'");
Dans la chaîne passée au shell entre guillemets simples, vous échappez les autres guillemets simples par terminer le guillemet simple actuel ( '
), commencer un guillemet double ( "
), ajouter un guillemet simple échappé ( \'
), fermer le guillemets doubles ( "
) et continuer la chaîne entre guillemets simples ( '
).
Ensemble, nous écrivons ceci comme '" \ '"'
, avec le contexte, c'est bli '" \' "'single-quote-inside-json'" \ '"' bla
, qui devient / bin / bash -c 'bli' "\ '"' guillemet simple-dans-json '"\'" 'bla'
.
Pourquoi si compliqué? p>
La raison pour laquelle cela est nécessaire peut être trouvée dans la page de manuel de bash (1):
Un guillemet simple peut ne pas apparaître entre guillemets simples, même s'il est précédé d'une barre oblique inverse.
C'est pourquoi nous devons terminer le guillemet simple, commencer un guillemet double (où le guillemet simple peut être échappé), terminer le guillemet double et continuer à nouveau notre guillemet simple.
Merci mec. J'ai utilisé l'une des méthodes suggérées précédemment pour résoudre ce problème.
Suggère fortement d'utiliser Apache Http Client ou une autre bibliothèque HTTP Java au lieu d'exécuter CURL sur l'IPC. Vous rendez votre programme Java moins portable en exécutant des processus tiers à partir du code. Au moins, vous devrez modifier votre code pour UNIX (Linux, FreeBSD, MacOS X) et Windows lors de l'exécution de CURL.
J'ai modifié votre titre afin que votre question soit mieux trouvée par les personnes ayant des problèmes similaires.