3

我有这个简单的红宝石脚本:

redcricket@dev-006:~$ cat simple.rb  
#!/usr/local/bin/ruby

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

当我运行它时,我得到的唯一输出是这个......

redcricket@dev-006:~$ ./simple.rb  
total 32

......我所期望的是这个......

redcricket@smp-mig-dev-006:~$ 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 吗?

谢谢!

4

4 回答 4

4

传递给的块只IO#popen执行一次。这不是一个循环。将传递给块的对象视为File¹。如果第二个参数IO#popen"r"你可以读到File;如果是的话,"w"你可以写信给它。在控制流离开块后,子进程应该是死的,并且IO您用来访问它的对象不再有效也不再可用。

如果您想获取一个行数组,请调用readlines块的参数。如果您想遍历它们,请调用each,即

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

¹ 准确地说,它是IO.

于 2012-12-05T21:42:16.257 回答
4

RubyIO#gets方法只是从 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 }
于 2012-12-05T21:42:34.820 回答
2

我喜欢:

IO.popen 'ls -l', 'r+' do |f|
  puts f.gets until f.eof?
end
于 2012-12-05T21:46:03.910 回答
2

传递给的块IO.popen只被调用一次,传递一个表示已创建管道的 IO 对象。

由于您只gets在该对象上调用一次,因此您只会收到该命令的单行输出。要获得更多行,您需要遍历 IO 对象:

IO.popen %w{ls -l}, 'r' do |pipe|
  pipe.each do |line|
    puts "|#{line}"
  end
end
于 2012-12-05T21:54:14.380 回答