web-dev-qa-db-fra.com

Ruby, Différence entre exec, system et% x () ou Backticks

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.

349
Mr. Black

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
_
386
Konrad Reiche

Voici un organigramme basé sur cette réponse . Voir aussi, en utilisant script pour émuler un terminal .

enter image description here

225
Ian

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.

100
William Pursell