Quelle est la différence entre les méthodes Ruby suivantes?
exec
, system
et %x()
ou Mises en arrière
Je sais qu'ils sont habitués à exécuter des commandes de terminal par programme via Ruby, mais j'aimerais savoir pourquoi il y a trois façons différentes de le faire.
système
La méthode system
appelle un programme système. Vous devez fournir la commande en tant qu'argument de chaîne à cette méthode. Par exemple:
_>> system("date")
Wed Sep 4 22:03:44 CEST 2013
=> true
_
Le programme appelé utilisera les objets STDIN
, STDOUT
et STDERR
actuels de votre programme Ruby. En fait, la valeur de retour réelle est soit true
, false
ou nil
. Dans l'exemple, la date a été imprimée via l'objet IO de STDIN
. La méthode retournera true
si le processus s'est terminé avec un statut nul, false
si le processus s'est terminé avec un statut différent de zéro et nil
si l'exécution a échoué.
Un autre effet secondaire est que la variable globale _$?
_ est définie sur un objet Process::Status
. Cet objet contiendra des informations sur l'appel lui-même, y compris l'identificateur de processus (PID) du processus appelé et le statut de sortie.
_>> system("date")
Wed Sep 4 22:11:02 CEST 2013
=> true
>> $?
=> #<Process::Status: pid 15470 exit 0>
_
Backticks
Backticks (``) appelle un programme système et renvoie sa sortie. Contrairement à la première approche, la commande n'est pas fournie via une chaîne, mais en la plaçant dans une paire de backticks.
_>> `date`
=> Wed Sep 4 22:22:51 CEST 2013
_
La variable globale _$?
_ est également définie à l'aide des backticks. Avec les backticks, vous pouvez également utiliser l’interpolation de chaîne.
% x ()
Utiliser _%x
_ est une alternative au style de piqûres croisées. Il renverra la sortie aussi. Comme ses parents _%w
_ et _%q
_ (entre autres), tout délimiteur suffira tant que les délimiteurs de type crochet seront identiques. Cela signifie que %x(date)
, _%x{date}
_ et _%x-date-
_ sont tous des synonymes. Comme les backticks _%x
_ peut utiliser l’interpolation de chaîne.
exec
En utilisant Kernel#exec
, le processus en cours (votre script Ruby est remplacé) par le processus appelé via exec
. La méthode peut prendre une chaîne en argument. Dans ce cas, la chaîne sera soumise à une expansion du shell. Lorsque vous utilisez plusieurs arguments, le premier est utilisé pour exécuter un programme et les éléments suivants sont fournis en tant qu'arguments au programme à appeler.
Open3.popen3
Parfois, les informations requises sont écrites sur une entrée standard ou une erreur standard et vous devez également en prendre le contrôle. Ici Open3.popen3
est pratique:
_require 'open3'
Open3.popen3("curl http://example.com") do |stdin, stdout, stderr, thread|
pid = thread.pid
puts stdout.read.chomp
end
_
Voici un organigramme basé sur cette réponse . Voir aussi, en utilisant script
pour émuler un terminal .
Ils font des choses différentes. exec
remplace le processus actuel par le nouveau processus et ne revient jamais. system
appelle un autre processus et renvoie sa valeur de sortie au processus actuel. Utiliser des backticks appelle un autre processus et renvoie la sortie de ce processus au processus actuel.