Recherche…


Introduction

Il existe plusieurs façons d’interagir avec le système d’exploitation. Depuis Ruby, vous pouvez exécuter des commandes ou des sous-processus shell / système.

Remarques

Exec:
Les fonctionnalités d'Exec sont très limitées et, une fois exécutées, elles quitteront le programme Ruby et exécuteront la commande.

La commande système:
La commande System s'exécute dans un sous-shell au lieu de remplacer le processus en cours et renvoie true ou nill. La commande système est, comme backticks, une opération de blocage dans laquelle l'application principale attend que le résultat de l'opération du système soit terminé. Ici, l'opération principale n'a jamais à se soucier de capturer une exception déclenchée par le processus enfant.

La sortie de la fonction système sera toujours vraie ou nulle selon que le script a été exécuté ou non. Par conséquent, chaque erreur lors de l'exécution du script ne sera pas transmise à notre application. L'opération principale n'a jamais à s'inquiéter de la capture d'une exception générée par le processus enfant. Dans ce cas, la sortie est nulle car le processus enfant a déclenché une exception.
C'est une opération de blocage où le programme Ruby attendra que l'opération de la commande se termine avant de continuer.
L'opération du système utilise fork pour bifurquer le processus en cours, puis exécute l'opération donnée en utilisant exec.

Les backticks (`):
Le caractère backtick est généralement situé sous la touche d'échappement sur le clavier. Backticks s'exécute dans un sous-shell au lieu de remplacer le processus en cours et renvoie le résultat de la commande.
Ici, nous pouvons obtenir la sortie de la commande mais le programme se bloquera lorsqu'une exception est générée.
S'il existe une exception dans le sous-processus, cette exception est donnée au processus principal et le processus principal peut se terminer si l'exception n'est pas gérée. C'est une opération de blocage où le programme Ruby attendra que l'opération de la commande se termine avant de continuer.
L'opération du système utilise fork pour bifurquer le processus en cours, puis exécute l'opération donnée en utilisant exec.

IO.popen:
IO.popen s'exécute dans un sous-processus. Ici, l'entrée standard de sous-processus et la sortie standard sont connectées à l'objet IO.

Popen3:
Popen3 vous permet d'accéder à l'entrée standard, à la sortie standard et à l'erreur standard.
L'entrée et la sortie standard du sous-processus seront renvoyées dans les objets IO.

$? (identique à $ CHILD_STATUS)
Peut être utilisé avec les opérations backticks, system () ou% x {} et donnera le statut de la dernière commande exécutée par le système.
Cela peut être utile pour accéder aux exitstatus et pid .

$?.exitstatus

Méthodes recommandées pour exécuter le code shell en Ruby:

Open3.popen3 ou Open3.capture3:
Open3 utilise en fait simplement la commande spawn de Ruby, mais vous offre une API bien meilleure.

Open3.popen3

Popen3 s'exécute dans un sous-processus et renvoie stdin, stdout, stderr et wait_thr.

require 'open3'
stdin, stdout, stderr, wait_thr = Open3.popen3("sleep 5s && ls")
puts "#{stdout.read} #{stderr.read} #{wait_thr.value.exitstatus}"

ou

require 'open3'
cmd = 'git push heroku master'
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
  puts "stdout is:" + stdout.read
  puts "stderr is:" + stderr.read
end

va sortir: stdout est: stderr est: fatal: Pas un dépôt git (ou l'un des répertoires parents): .git

ou

require 'open3'
cmd = 'ping www.google.com'
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
  while line = stdout.gets
    puts line
  end
end

va sortir:

En cliquant sur www.google.com [216.58.223.36] avec 32 octets de données:
Réponse de 216.58.223.36: octets = 32 fois = 16ms TTL = 54
Réponse de 216.58.223.36: octets = 32 fois = 10ms TTL = 54
Réponse de 216.58.223.36: octets = 32 heure = 21ms TTL = 54
Réponse de 216.58.223.36: octets = 32 fois = 29ms TTL = 54
Statistiques de ping pour 216.58.223.36:
Paquets: Envoyé = 4, Reçu = 4, Perdu = 0 (perte de 0%),
Temps d'aller-retour approximatifs en milli-secondes:
Minimum = 10ms, Maximum = 29ms, Moyenne = 19ms


Open3.capture3:

require 'open3'

stdout, stderr, status = Open3.capture3('my_funky_command', 'and', 'some', 'argumants')
if status.success?
  # command completed successfully, do some more stuff
else
  raise "An error occured"
end

ou

Open3.capture3('/some/binary with some args')  

Non recommandé en raison des frais généraux supplémentaires et du potentiel d'injection de coquille.

Si la commande lit à partir de stdin et que vous voulez lui donner des données:

Open3.capture3('my_funky_command', stdin_data: 'read from stdin')  

Exécutez la commande avec un répertoire de travail différent, en utilisant chdir:

Open3.capture3('my_funky_command', chdir: '/some/directory')  

Des moyens classiques pour exécuter du code shell en Ruby:

Exec:

exec 'echo "hello world"'

ou

exec ('echo "hello world"')

La commande système:

system 'echo "hello world"'

Produira "hello world" dans la fenêtre de commande.

ou

system ('echo "hello world"')

La commande système peut renvoyer un true si la commande a réussi ou non.

result = system 'echo "hello world"'
puts result  # will return a true in the command window

Les backticks (`):

echo "hello world" Affiche "hello world" dans la fenêtre de commande.

Vous pouvez également attraper le résultat.

result = `echo "hello world"`  
puts "We always code a " + result  

IO.popen:

# Will get and return the current date from the system
IO.popen("date") { |f| puts f.gets }


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow