Exécution d’une commande à partir de Ruby affichant et capturant la sortie

Existe-t-il un moyen d’exécuter une commande (shell) à partir de Ruby, mais également de capturer la sortie? Peut-être avec l’aide d’un bijou?

Ce que je veux dire par affichage, ce n’est pas l’imprimer à la fin, mais tel qu’il apparaît, de sorte que l’utilisateur obtient le feedback de ce qui se passe lors de l’exécution de commandes lentes.

Vous pouvez lancer un appel système comme ceci:

`sleep --help` 

Ou comme ça

 system "sleep --help" 

Ou

 %x{ sleep --help } 

Dans le cas du system il imprimera les résultats et renverra true ou nil , les deux autres méthodes renverront la sortie

PS Oh. Il s’agit d’afficher en temps réel.

Alors. Vous pourriez utiliser quelque chose comme ceci:

 system("ruby", "-e 100.times{|i| pi; sleep 1}", out: $stdout, err: :out) 

Pour imprimer des données en temps réel et les stocker dans une variable:

 output = [] r, io = IO.pipe fork do system("ruby", "-e 3.times{|i| pi; sleep 1}", out: io, err: :out) end io.close r.each_line{|l| puts l; output << l.chomp} #=> 0 #=> 1 #=> 2 p output #=> ['0', '1', '2'] 

Ou utiliser du popen

 output = [] IO.popen("ruby -e '3.times{|i| pi; sleep 1}'").each do |line| p line.chomp output << line.chomp end #=> '0' #=> '1' #=> '2' p output #=> ['0', '1', '2'] 

Vous pouvez redirect la sortie

 system 'uptime > results.log' 

ou enregistrez les résultats.

 result = `uptime` result = %x[uptime] 

voir ici Obtenir des informations de progression ou de sortie en temps réel est plus compliqué, je doute qu’il existe une solution simple. Peut-être est-ce possible avec des fonctions de gestion de processus avancées telles que Open3.popen3 . Vous pouvez également essayer d’utiliser un pseudo-terminal avec pty et y graver la sortie .

J’ai utilisé open3 pour capturer la sortie de la commande shell exécutée à partir du code open3 .

 require 'open3' stdout, stdeerr, status = Open3.capture3("ls") puts stdout 

Si vous souhaitez explorer une solution en dehors de la bibliothèque standard, vous pouvez également utiliser Mixlib::ShellOut pour Mixlib::ShellOut à la fois la sortie et la capturer:

 require 'mixlib/shellout' cmd = 'while true; do date; sleep 2; done' so = Mixlib::ShellOut.new(cmd) so.live_stream = $stdout so.run_command out = so.stdout