Can I get continuous output from system calls in Ruby?

When you use a system call in a Ruby script, you can get the output of this command as follows:

output = `ls`
puts output

This is what this question was about.

But is there a way to show the output of a continuous system call? For example, if you run this secure copy command to retrieve a file from the server via SSH:

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

... it shows a continuous exit with loading progress. But this:

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

... does not record this conclusion.

How to show the current download progress from my Ruby script?

+5
source share
5 answers

Try:

IO.popen("scp -v user@server:remoteFile /local/folder/").each do |fd|
  puts(fd.readline)
end
+9
source

, SCP ( forking ). Net:: SCP ( Net:: *) Capistrano .

http://net-ssh.rubyforge.org/ , .

+3

, , , . script, , .

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

# Establish the SSH session
ssh = Net::SSH.start("IP Address", "username on server", :password => "user 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!"
+2

IO.popen? , , .

0

stderr stdout :

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

This should capture both stderr and stdout. You can capture stderr only by throwing stdout out:

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

Then you can use IO.popen.

0
source

All Articles