Comment exécuter des commandes système à partir de Ruby

Si vous voulez exécuter une commande externe à partir de Ruby…

…comme wkhtmltopdf pour convertir un fichier HTML en PDF.

Il existe quelques méthodes Ruby que vous pouvez utiliser.

Selon la méthode utilisée, vous obtiendrez des résultats différents.

Explorons ces méthodes ensemble !

La méthode système Ruby

La méthode système Ruby est la façon la plus simple d’exécuter une commande externe.

Elle ressemble à ceci :

system("ls")

Notez que system imprimera la sortie de la commande au fur et à mesure.

De plus, le système fera attendre votre programme Ruby jusqu’à ce que la commande soit terminée.

Essayez ceci:

system("sleep 2")

Il existe des moyens d’exécuter des commandes en arrière-plan comme nous le verrons plus tard.

Le système peut renvoyer 3 valeurs possibles :

  • true si la commande a fonctionné
  • false si la commande renvoie un code d’erreur
  • nil si l’exécution de la commande échoue (commande non trouvée)

Vous pouvez obtenir le code d’état de sortie de la dernière commande externe que vous avez exécutée avec la variable globale $?. Ce code d’état peut vous donner plus d’informations sur la raison pour laquelle la commande a échoué.

Qu’est-ce que l’expansion de l’interpréteur de commandes ?

Lorsque vous exécutez une commande externe avec system, vous obtiendrez l’effet « expansion de l’interpréteur de commandes ».

L’expansion de l’interpréteur de commandes est lorsque l’interpréteur de commandes (sh/bash/zsh) prend certains caractères spéciaux (*, ? et ")# "best"

This will not change the current environment of your Ruby application.

%x / Kernel#`

If you want to get the output from the command you're running, instead of displaying it then you can use %x ou la méthode Kernel#`.

Ils font la même chose.

Voici un exemple:

`ls`

Un autre avec %x:

%x|ls|

Ces deux exemples retourneront une chaîne de caractères avec la sortie de la commande ls.

Notez que vous devez toujours attendre que la commande se termine à moins que vous ne l'exécutiez à l'intérieur d'un thread.

Comment utiliser Fork + Exec pour exécuter des commandes externes sur un processus séparé

Forking fait une copie de votre processus actuel (votre application Ruby) puis vous pouvez remplacer cette copie par un autre processus en utilisant exec.

Note : La méthode fork n'est pas disponible sur Windows.

C'est un motif populaire dans le monde Unix.

Voici comment cela fonctionne :

fork { exec("ls") }

Ceci va exécuter ls sur un autre processus & afficher sa sortie.

Parce que cette commande est exécutée dans un autre processus, elle ne bloquera pas l'exécution de votre app Ruby comme la méthode system ou %x.

Important:

Si vous utilisez exec sans fork, vous allez remplacer votre processus actuel.

Cela signifie que votre programme Ruby va se terminer.

Comment utiliser la méthode Popen pour une communication bidirectionnelle avec un programme externe

Si vous avez besoin :

  • d'un plus grand contrôle sur le processus
  • d'une communication bidirectionnelle

alors la méthode IO.popen est ce que vous recherchez.

Dans l'exemple suivant, j'utilise la méthode popen pour lancer un irbprocessus, puis lui envoyer des entrées &lire la sortie.

Voici l'exemple :

r = IO.popen("irb", "r+")r.write "puts 123 + 1\n"3.times { puts r.gets }r.write "exit\n"

Cette rvariable est un objet d'entrée/sortie, cela signifie que vous pouvez écrire &lire dessus comme un fichier ordinaire.

L'utilisation de popen signifie également que votre commande externe s'exécutera sur son propre processus, de sorte que vous n'avez pas à l'exécuter sur un thread.

Il existe également une méthode popen3 dans la bibliothèque standard.

La différence avec la popen régulière est qu'elle divisera les messages d'erreur de sortie & réguliers en objets IO séparés.

Conclusion

Vous avez appris les différentes façons d'interagir avec les commandes externes dans Ruby.

Soyez prudent avec celles-ci !

Ne passez aucune sorte d'entrée utilisateur dans ces commandes à moins que vous ne vouliez un problème de sécurité dans votre app Ruby.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.