2011-03-04 52 views
5

當您使用Ruby腳本的系統調用,就可以得到該命令的輸出是這樣的:我可以從Ruby中的系統調用獲得連續輸出嗎?

output = `ls` 
puts output 

這就是this question約。

但是有沒有辦法顯示系統調用的輸出連續?例如,如果你運行這個安全複製命令,獲取某個服務器上的文件通過SSH:

scp [email protected]:remoteFile /some/local/folder/ 

...它顯示了下載的進度連續輸出。但是這個:

output = `scp [email protected]:remoteFile /some/local/folder/` 
puts output 

...不捕獲那個輸出。

如何從Ruby腳本中顯示正在進行的下載進度?

+1

你這裏有兩個正交的問題,因爲SCP默認情況下只輸出到終端,你需要* SCP -v * – tokland 2011-03-04 14:09:17

+0

@tokland - 使其到達輸出調試消息,但不是說我會看到傳輸進度如果我只是單獨跑scp。我認爲這些不能達到標準輸出,並且我沒有看到scp將它們發送到那裏的選項。 – 2011-03-04 14:39:36

+0

顯然scp發送進度信息到「交互式終端」?不知道如何捕獲... – 2011-03-04 14:45:27

回答

9

嘗試:

IO.popen("scp -v [email protected]:remoteFile /local/folder/").each do |fd| 
    puts(fd.readline) 
end 
+0

這適用於獲取標準輸出消息,但它似乎不是scp發送其傳輸進度的地方。所以我想我的問題是現在用scp。 – 2011-03-04 14:40:26

+0

這回答了我提出的問題 - scp不能正常輸出的事實竟然是一個意想不到的細節。 – 2011-03-04 18:45:29

+0

請參閱下面的答案,瞭解如何從Ruby標準庫中獲得輸出。 – 2011-03-04 18:51:10

0

你試過IO.popen嗎? 您應該能夠在進程仍在運行時讀取輸出並相應地解析它。

3

我想你會使用Ruby標準庫來處理SCP(而不是派生一個shell進程)有更好的運氣。 Net :: SCP庫(以及整個Net :: *庫)功能齊全,可與Capistrano一起用於處理遠程命令。

結帳http://net-ssh.rubyforge.org/爲可用的概要。

+0

這看起來很有希望! net-scp文檔在這裏:http://net-ssh.github.com/scp/v1/api/index.html另外,本教程演示如何在傳輸過程中輸出進度:http://ruby.about。 com/od/ssh/ss/netscp_4.htm – 2011-03-04 15:14:49

+0

這就是我最終做的。我能夠通過將塊傳遞給scp對象來顯示下載進度的運行計數器。看到我的答案完整的腳本。 – 2011-03-04 18:46:55

0

重定向錯誤輸出到標準輸出可以爲你工作:

output = `scp [email protected]:remoteFile /some/local/folder/ 2>&1` 
puts output 

這應該同時捕獲標準錯誤和標準輸出。您只能扔掉標準輸出捕獲標準錯誤:

output = `scp [email protected]:remoteFile /some/local/folder/ 2>&1 >/dev/null` 
puts output 

然後可以使用IO.popen

2

托特蘭回答了我提出的問題,但亞當的方法就是我最終使用的方法。這是我完成的腳本,其中確實顯示正在下載的字節的運行計數,並且還完成了一個百分比。

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

是的,這是最好的方法,當使用好的語言只是合乎邏輯的依賴他們的庫。 – tokland 2011-03-04 20:47:20

相關問題