ho un semplice script di Ruby che assomiglia a questocome si fa a uscita pipe da uno script Ruby per 'testa' senza ottenere un tubo rotto errore
require 'csv'
while line = STDIN.gets
array = CSV.parse_line(line)
puts array[2]
end
Ma quando cerco di utilizzare questo script in un oleodotto Unix in questo modo, ottengo 10 linee di produzione, seguita da un errore:
ruby lib/myscript.rb < data.csv | head
12080450
12080451
12080517
12081046
12081048
12081050
12081051
12081052
12081054
lib/myscript.rb:4:in `write': Broken pipe - <STDOUT> (Errno::EPIPE)
c'è un modo per scrivere lo script Ruby in un modo che impedisce l'eccezione tubo rotto venga sollevata?
Se la testa chiude il flusso, allora perché '' $ stdout.closed ancora return false e perché l'errore non accadrà immediatamente, ma solo dopo che molte righe sono state scritte nel vuoto? Penso che head mantenga il flusso aperto, ma non lo legga più, il che fa sì che il buffer sia pieno in un punto che causa il punto rotto. – sepp2k
@ sepp2k - Ci sono probabilmente un paio di cose che succedono qui: 1, la modalità di buffering predefinita per le modifiche di stdout da orientata alla linea verso il blocco quando si utilizza una pipeline, quindi sarà necessario scorrere tra ogni scrittura. 2, 'head' ha bisogno di una possibilità di esecuzione per chiudere il flusso, ma molti più byte di dati potrebbero essere stati scritti prima che abbia la possibilità di funzionare. Ho scritto una variante dello script con '$ stdout.flush; sleep 0.1' tra ogni 'write', e in questo caso' $ stdout.closed? 'funziona. –
@AidanCully: Ah, molto interessante. – sepp2k