Могу ли я получить непрерывный вывод из системных вызовов в Ruby? - PullRequest
5 голосов
/ 04 марта 2011

Когда вы используете системный вызов в сценарии Ruby, вы можете получить вывод этой команды следующим образом:

output = `ls`
puts output

Вот о чем был вопрос .

Но есть ли способ показать непрерывный вывод системного вызова?Например, если вы запустите эту команду защищенного копирования, чтобы получить файл с сервера через SSH:

scp user@someserver:remoteFile /some/local/folder/

... он показывает непрерывный вывод с ходом загрузки.Но это:

output = `scp user@someserver:remoteFile /some/local/folder/`
puts output

... не фиксирует этот вывод.

Как я могу показать текущий процесс загрузки из моего скрипта Ruby?

Ответы [ 5 ]

9 голосов
/ 04 марта 2011

Попробуйте:

IO.popen("scp -v user@server:remoteFile /local/folder/").each do |fd|
  puts(fd.readline)
end
3 голосов
/ 04 марта 2011

Я думаю, вам лучше бы использовать стандартную библиотеку ruby ​​для обработки SCP (в отличие от разветвления процесса оболочки).Библиотека Net :: SCP (а также все библиотеки Net :: *) являются полнофункциональными и используются вместе с Capistrano для обработки удаленных команд.

Checkout http://net -ssh.rubyforge.org / для краткого изложения того, что доступно.

2 голосов
/ 04 марта 2011

Токланд ответил на вопрос, когда я его задал, но подход Адама был тем, что я в итоге использовал.Вот мой законченный скрипт, который показывает текущее количество загруженных байтов, а также процент выполнения.

require 'rubygems'
require 'net/scp'
puts "Fetching file"

# Establish the SSH session
ssh = Net::SSH.start("IP Address", "username on server", :password => "user's password on server", :port => 12345)

# Use that session to generate an SCP object
scp = ssh.scp

# Download the file and run the code block each time a new chuck of data is received
scp.download!("path/to/file/on/server/fileName", "/Users/me/Desktop/") do |ch, name, received, total|

  # Calculate percentage complete and format as a two-digit percentage
  percentage = format('%.2f', received.to_f / total.to_f * 100) + '%'

  # Print on top of (replace) the same line in the terminal
  # - Pad with spaces to make sure nothing remains from the previous output
  # - Add a carriage return without a line feed so the line doesn't move down
  print "Saving to #{name}: Received #{received} of #{total} bytes" + " (#{percentage})               \r"

  # Print the output immediately - don't wait until the buffer fills up
  STDOUT.flush
end

puts "Fetch complete!"
0 голосов
/ 04 марта 2011

Перенаправление stderr в stdout может работать для вас:

output = `scp user@someserver:remoteFile /some/local/folder/ 2>&1`
puts output

Это должно охватить как stderr, так и stdout.Вы можете захватить stderr только выбрасывая stdout:

output = `scp user@someserver:remoteFile /some/local/folder/ 2>&1 >/dev/null`
puts output

Затем вы можете использовать IO.popen.

0 голосов
/ 04 марта 2011

вы пробовали с IO.popen? Вы должны быть в состоянии прочитать выходные данные, пока процесс еще выполняется, и соответственно проанализировать их.

...