Ruby未定义的方法`mtime&#39; for <net :: sftp :: request:0x007fa2799d41d0>(NoMethodError)我以为.mtime是由前一个字符串</net :: sftp :: request定义的:0x007fa2799d41d0>

时间:2014-05-22 02:46:41

标签: ruby ssh find sftp

直到第56行,我不知道我是否正确使用mtime,我认为字符串before.mtime定义了它。我也不确定哪个mtime导致错误,这里是第56行:

如果File.stat(local_file).mtime&gt; Time.at(rstat.mtime)

这是我在运行此代码时得到的错误:

box.ru:56:in `block (3 levels) in <main>': undefined method `mtime' for #<Net::SFTP::Request:0x007fa2799d41d0> (NoMethodError)

rstat = sftp.stat(remote_file)所以第二个mtime也应该被定义,除非配置错误的remote_file ..谢谢你看看!

#!/usr/bin/env ruby
require 'rubygems'
require 'net/ssh'
require 'net/sftp'
require 'highline/import'
require 'find'

host = 'server'
local_path = '/Users/awesome1/Development/box'
remote_path = '/home/awesome2/box'

def sanitize_string(string_name)
string_name.gsub(/[^\w\.\-]/,"_")
end


puts "box username:"
user0 = gets.chomp
user = sanitize_string(user0)

pass0 = ask("Enter password for #{user}: ") { |q| q.echo = false }
pass = sanitize_string(pass0)

puts 'connecting to box...'
Net::SSH.start( host, user, :password => pass ) do|ssh|
result = ssh.exec!("cd #{remote_path} && ls")
 puts result
   ssh.sftp.connect do |sftp| 
 puts 'Checking for files which need updating'
 Find.find(local_path) do |local_file|
     next if File.stat(local_file).directory?
     remote_file = remote_path + local_file.sub(local_path, '')

     begin
     remote_dir = File.dirname(remote_file)
     sftp.stat(remote_dir)
 rescue Net::SFTP::Operations::StatusException => e
   raise unless e.code == 2
   sftp.mkdir(remote_dir, :mode => dir_perm)
 end 
   begin
   rstat = sftp.stat(remote_file)
 rescue Net::SFTP::Operations::StatusException => e
   raise unless e.code == 2
   sftp.put_file(local_file, remote_file)
   sftp.setstat(remote_file, :permissions => file_perm)
   next
 end

 if File.stat(local_file).mtime > Time.at(rstat.mtime)
   puts "Copying #{local_file} to #{remote_file}"
   ssh.sftp.upload(local_file, remote_file)
  end
 end
end
end 

1 个答案:

答案 0 :(得分:2)

1)除非您的代码正确缩进,否则不要在堆栈溢出或任何其他计算机编程论坛上发布。

if File.stat(local_file).mtime > Time.at(rstat.mtime)
     

这是我在运行此代码时得到的错误:

box.ru:56:in block (3 levels) in <main>': undefined method mtime' for 
<Net::SFTP::Request:0x007fa2799d41d0> (NoMethodError)

2)错误消息暗示rstat是Net::SFTP::Request类型的对象,如果您在此查看NET::SFTP文档:

http://net-ssh.rubyforge.org/sftp/v2/api/

你会发现mtime()不是Net::SFTP::Request类的实例方法,即你不能在Net::SFTP::Request对象上调用mtime()。

该行:

ssh.sftp.connect do |sftp|

将类型为NET::SFTP::Session的对象分配给sftp,因此sftp.stat()必须返回类型为Net::SFTP::Request的对象。如果查看NET::SFTP::Session#stat()的文档,他们会将您引用到lstat()文档,如果单击lstat()的链接,则lstat()文档会说:

  

该方法立即返回Request对象。

这个班级真的只是命名为“请求”吗?点击“请求”链接,您将在页面顶部看到:

Net::SFTP::Request

...并且没有为该类列出名为mtime()的方法。也许mtime()方法包含在某个父类或某个包含在某个地方的模块中?父类被列为Object(在Net::SFTP::Request的正下方),Net::SFTP::Request有一个名为Constants::PacketTypes的包含模块 - 但在Object或{中没有mtime()方法{1}}。

出于某种原因,你似乎认为Constants::PacketTypes返回一个File对象 - 它没有; sftp.stat()返回一个sftp.stat(remote_file)对象。但是,如果在调用stat()时指定一个块(请参阅lstat()docs),那么该块将传递一个Net :: SFTP :: Response对象,并根据lstat()docs:

  

响应的:attrs属性将包含一个Attributes   适用于协议版本的实例(请参阅   Protocol :: V01 :: Attributes,Protocol :: V04 :: Attributes,and   协议:: V06 ::属性)。

检查协议:: V06 :: Attributes的文档显示响应中有:mtime属性,并且:

  

所有上述属性都作为方法公开(尽管不是全部   将使用来自服务器的非零值设置。)

回到lstat()文档并再次查看示例,可以看出你做了类似的事情:

Net::SFTP::Request