Lors de l'utilisation de la sortie standard dans Ruby, il semble que les règles de mise en mémoire tampon flash diffèrent selon que la destination de sortie standard est la console ou une autre commande.
--Si la sortie standard est connectée à une autre commande, mettez-la en mémoire tampon.
Vérifions cela brièvement. Code Ruby qui renvoie «true» si la sortie standard est connectée à la console, «false» si elle est connectée à la commande, puis renvoie les nombres de 0 à 4 sur la sortie standard toutes les secondes. est.
main.rb
puts "STDOUT.isatty = #{STDOUT.isatty}"
5.times do |x|
sleep 1
puts x
end
Les commandes cmd.rb
et console.rb
suivantes exécutent la sortie standard de ruby main.rb
en la connectant à un tube ou à une console, et ajoutent un horodatage au résultat de sortie.
cmd.rb
require 'open3'
#Lisez ligne par ligne à partir d'E / S en lecture seule, ajoutez l'horodatage et la sortie.
puts '*** main.Lorsque la sortie standard de rb est connectée à une autre commande***'
Open3.popen3('ruby main.rb') do |stdin, stdout, stderr, wait_thr|
stdout.each do |line|
timestamp = Time.now.strftime('%F %T')
puts "#{timestamp} #{line}"
end
end
console.rb
require 'pty'
#Lisez ligne par ligne à partir d'E / S en lecture seule, ajoutez l'horodatage et la sortie.
puts '*** main.Lorsque la sortie standard de rb est connectée à la console***'
PTY.spawn('ruby main.rb') do |read, write, pid|
read.each do |line|
timestamp = Time.now.strftime('%F %T')
puts "#{timestamp} #{line}"
end
end
Les résultats d'exécution de «cmd.rb» et «console.rb» sont les suivants.
$ ruby cmd.rb 2>/dev/null
*** main.Lorsque la sortie standard de rb est connectée à une autre commande***
2020-07-05 16:45:09 STDOUT.isatty = false
2020-07-05 16:45:09 0
2020-07-05 16:45:09 1
2020-07-05 16:45:09 2
2020-07-05 16:45:09 3
2020-07-05 16:45:09 4
$ ruby console.rb 2>/dev/null
*** main.Lorsque la sortie standard de rb est connectée à la console***
2020-07-05 16:45:11 STDOUT.isatty = true
2020-07-05 16:45:12 0
2020-07-05 16:45:13 1
2020-07-05 16:45:14 2
2020-07-05 16:45:15 3
2020-07-05 16:45:16 4
Si vous regardez les horodatages, vous pouvez voir que le main.rb
, qui a une sortie standard connectée au tuyau, est mis en mémoire tampon, mais s'il est connecté à la console, il est vidé ligne par ligne.
Je pense qu'il y a plusieurs façons de le faire, mais est-ce celle qui me vient à l'esprit pour le moment?
--Set STDOUT.sync = true
pour mettre la sortie standard en mode synchro
--Appelez STDOUT.flush
à tout moment.
Expérimentons avec le premier. Modifiez le main.rb
ci-dessus comme suit.
main.rb
$stdout.sync = true
puts "STDOUT.isatty = #{STDOUT.isatty}"
5.times do |x|
sleep 1
puts x
end
Si vous exécutez cmd.rb
, qui connecte la sortie standard de main.rb
à une autre commande, vous pouvez voir qu'elle n'est pas mise en mémoire tampon contrairement à avant.
$ ruby cmd.rb 2>/dev/null
*** main.Lorsque la sortie standard de rb est connectée à une autre commande***
2020-07-05 16:51:33 STDOUT.isatty = false
2020-07-05 16:51:34 0
2020-07-05 16:51:35 1
2020-07-05 16:51:36 2
2020-07-05 16:51:37 3
2020-07-05 16:51:38 4
Il semble y avoir différentes façons de faire cela, mais pour autant que je sache, "Redirigez $ stdout
vers StringIO
et affichez le contenu stocké dans StringIO
vers STDOUT
à tout moment." Il y a quelque chose comme ça. Dans ce cas, main.rb
devrait ressembler à ceci:
main.rb
require 'stringio'
StringIO.open do |io|
#Rediriger la sortie standard vers StringIO
$stdout = io
#Ceci est le principal original.Identique à rb
puts "STDOUT.isatty = #{STDOUT.isatty}"
5.times do |x|
sleep 1
puts x
end
#Déchargez le contenu stocké dans StringIO vers STDOUT
$stdout = STDOUT
io.rewind
puts io.read
end
Si vous exécutez console.rb
et voyez ce qui se passe lorsque main.rb
est connecté à la console, vous verrez qu'il est mis en mémoire tampon comme prévu.
$ ruby console.rb 2>/dev/null
*** main.Lorsque la sortie standard de rb est connectée à la console***
2020-07-05 16:56:38 STDOUT.isatty = true
2020-07-05 16:56:38 0
2020-07-05 16:56:38 1
2020-07-05 16:56:38 2
2020-07-05 16:56:38 3
2020-07-05 16:56:38 4