2
votes

Exécuter une ligne Bash avec des guillemets différents du code Java pour la requête Elasticsearch

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.


2 commentaires

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.


3 Réponses :


0
votes

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.


0 commentaires

2
votes

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);



1
votes

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.


1 commentaires

Merci mec. J'ai utilisé l'une des méthodes suggérées précédemment pour résoudre ce problème.