简单的Ruby SFTP示例语法错误

时间:2009-10-28 01:10:55

标签: ruby rubygems sftp net-sftp

我有一个看起来非常不稳定的问题,这是Ruby的问题还是我做过的事情?请帮助 - 我的项目停滞不前,直到我解决了这个问题。

鉴于此代码在Mac OS Leopard上运行:

require 'uri'
require 'net/ssh'
require 'net/sftp'
include Net

def copy_from_uri( uri, local_path )
    # SFTP copy
    SFTP.start( uri.host, uri.user, :password => 'password' ) do |sftp|
        puts "downloading from #{uri.host}, path #{uri.path}\n"
        sftp.download( uri.path, local_path )
    end
end

remote_uri = URI.parse( "sftp://example.com/test.mp4" )
local_file = "/tmp/remote_copy_test.mp4"
result = copy_from_uri( remote_uri, local_file );

什么会导致以下错误?

$ ruby sftp_fail.rb 
/Library/Ruby/Site/1.8/net/sftp.rb:43:in `start': undefined method `shutdown!' 
for nil:NilClass (NoMethodError)
    from sftp_fail.rb:8:in `copy_from_uri'
    from sftp_fail.rb:18

仅供参考我正确设置了RUBYOPT,因此宝石已加载,我的宝石是最新的,根据:

$gem list --local
net-sftp (2.0.2, 1.1.0)
net-ssh (2.0.15, 1.1.2)

3 个答案:

答案 0 :(得分:3)

它告诉你一些你试图调用关闭的对象!方法是零。现在,该代码不在您的示例中,因此很难说为什么会这样,但我非常怀疑它是该语言中的错误。

这种方法调用正在发生,所以也许您可以发布该代码?

result = copy_from_uri( remote_uri, local_file );

URI#parse永远不会返回nil(它会抛出异常),所以如果可能的话,看看这个方法体会有所帮助。

答案 1 :(得分:2)

此错误实际上是由于net-sftp v2.0.2中的错误:

def self.start(host, user, options={}, &block)
  # ...
rescue Object => anything
  begin
    session.shutdown!
  rescue Exception
    # swallow exceptions that occur while trying to shutdown
  end

  raise anything
end

当#start方法发生错误时,它会尝试关闭会话...但如果会话本身为nil,则会引发NoMethodErrorrescue Exception行试图吞下所有异常,但它实际上是在抢救Net::SFTP::Exception而不是根级异常。最近修复了这个问题(参见this commit)。

升级到net-sftp 2.0.4,您将不再会遇到这个模糊的错误。你仍然会收到一个错误,但是由于救援区中发生的新错误没有丢弃原始错误,因此它应该更有帮助。

答案 2 :(得分:1)

我刚刚遇到过这个,但这是由另一个原因造成的。我的文件主机已经更改了他们的RSA密钥,因此~/.ssh/known_hosts中的密钥不正确 - 这导致了与所示相同的错误,从SSH过滤掉了。删除无效密钥可以解决问题。