10
votes

Comment puis-je obtenir le stdouté d'un appel de système rubis () pendant qu'il est exécuté?

Semblable à Obtenir la sortie des appels système () dans Ruby , Je gère une commande système, mais dans ce cas, je dois émettre le stdout de la commande lors de son exécution.


2 commentaires

Il est curieux que vous devriez avoir quelque chose de spécial. Dans mon expérience, lorsque j'exécute un programme à l'aide de System , le stdout du programme enfant va au STDOUT du programme parent, ce qui semble être ce que vous voulez.


Cela peut également fonctionner: Stackoverflow.com/Questtions/2215455/...


3 Réponses :


14
votes

Comme dans la question liée, la réponse est à nouveau de ne pas utiliser système au tout sous le système ne supporte pas cela.

Cependant, cette fois-ci la solution ne doit pas utiliser backtacks , mais io.popen , qui renvoie un objet IO que vous pouvez utiliser pour lire l'entrée tel qu'il est généré.


1 commentaires

Merci, j'ai fini par utiliser io.popen ('command_to_run') {| io | tandis que (ligne = io.gets) met fin de ligne}



0
votes

Voici ma solution

def io2stream(shell, &block)
  Open3.popen3(shell) do |_, stdout, stderr|
    while line = stdout.gets
      block.call(line)
    end

    while line = stderr.gets
      block.call(line)
    end
  end
end

io2stream("ls -la", &lambda { |str| puts str })


1 commentaires

Cela ne fonctionnerait que pour certains programmes. On devrait lire STDOUT et STDERR dans deux threads parallèles, car les programmes sont autorisés à écrire sur ces sorties en parallèle.



1
votes

Si quelqu'un voudrait lire stdout code> et str> em> starr code>:
Il est important strong> de les lire en parallèle fort>, pas premier que l'autre. Parce que les programmes sont autorisés à produire à stdout code> et stardr code> à tour de rôle fort> et même en parallèle fort>. Donc, vous avez besoin threads forts>. Ce fait n'est même pas spécifique au rubis.

volé de Ici . P>

require 'open3'

cmd = './packer_mock.sh'
data = {:out => [], :err => []}

# see: http://stackoverflow.com/a/1162850/83386
Open3.popen3(cmd) do |stdin, stdout, stderr, thread|
  # read each stream from a new thread
  { :out => stdout, :err => stderr }.each do |key, stream|
    Thread.new do
      until (raw_line = stream.gets).nil? do
        parsed_line = Hash[:timestamp => Time.now, :line => "#{raw_line}"]
        # append new lines
        data[key].push parsed_line

        puts "#{key}: #{parsed_line}"
      end
    end
  end

  thread.join # don't exit until the external process is done
end


0 commentaires