2012-12-05 65 views
2

我有這個簡單的Ruby腳本:如何迭代popen輸出?

[email protected]:~$ cat simple.rb 
#!/usr/local/bin/ruby 

IO.popen 'ls -l', 'r+' do |f| 
     puts f.gets 
end 

,當我運行它唯一的輸出我得到的是這樣的......

[email protected]:~$ ./simple.rb 
total 32 

...我所期待的是這個...

[email protected]:~$ ls -l 
total 32 
drwxr-xr-x 4 redcricket co 4096 Dec 5 12:23 applications 
-rw-r--r-- 1 redcricket co 464 Oct 5 16:23 config 
drwxr-xr-x 72 redcricket co 4096 Dec 5 15:11 docs 
drwxr-xr-x 3 root root 4096 Dec 5 12:14 oradiag_root 
drwxr-xr-x 5 redcricket co 4096 Dec 5 16:22 platform 
-rwxr-xr-x 1 redcricket co 373 Dec 5 16:30 process_yum_output.rb 
-rwxr-xr-x 1 redcricket co 2159 Nov 28 16:24 SetupSSHPK.sh 
-rwxr-xr-x 1 redcricket co 142 Dec 5 16:31 simple.rb 

...我想我需要迭代f.gets莫名其妙?

謝謝!

回答

3

Ruby IO#gets method只是返回來自IO對象的下一行輸入。

爲了獲得所有的行,您可以反覆調用「gets」直到它爲零,或者撥打read獲取整個字符串,或撥打readlines獲取數組中的輸入行。

IO.popen('ls -l','r') { |f| puts $_ while f.gets } 
IO.popen('ls -l','r') { |f| puts f.read } 
IO.popen('ls -l','r') { |f| puts f.readlines } 
4

傳遞給IO#popen的塊被執行一次只有。這不是一個循環。考慮傳遞給塊的對象爲File¹。如果IO#popen的第二個參數是"r",那麼您可以閱讀File;如果是"w",您可以寫信給它。在控制流離開塊之後,子進程應該是死的,並且用於訪問它的對象既不是有效的,也不再可用。

如果您想獲取塊的參數上的一行數組,請致電readlines。如果你想在它們之間迭代,調用each,即

IO.popen("ls", "r") { |io| io.each { |line| puts line } } 

¹準確地說,它是IO一個實例。

+0

這工作正常(可能更好)沒有'readlines'。 – steenslag

+0

@steenslag,歡呼聲,好點。 – Jan

2

我喜歡:

IO.popen 'ls -l', 'r+' do |f| 
    puts f.gets until f.eof? 
end 
2

傳遞給IO.popen該塊只調用一次,被傳遞表示所創建的管中的IO對象。

由於您只需在該對象上調用gets一次,您將只收到該命令的單行輸出。爲了獲得更多的行,你需要迭代IO對象:

IO.popen %w{ls -l}, 'r' do |pipe| 
    pipe.each do |line| 
    puts "|#{line}" 
    end 
end