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 irb
processus, 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 r
variable 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.